""" Экспериментальная часть. Пункт 2: Инструменты замера времени. Цель: предоставить функции для многократного измерения времени выполнения операций со структурами данных (LinkedList, HashTable, BST). Особенности: - Используется time.perf_counter() для высокой точности. - Каждый эксперимент повторяется min_runs раз (по умолчанию 5), результаты сохраняются. - Вычисляется среднее арифметическое и список всех замеров. - Результаты можно напрямую сохранить в CSV. """ import time from typing import List, Tuple, Callable, Any import random # Предполагается, что generate_test_data из пункта 1 уже определена # from experimental_part1 import generate_test_data # если код в другом файле # ========== 1. Базовые замеры ========== def measure_time(func: Callable, *args, **kwargs) -> float: """ Измеряет время выполнения функции func(*args, **kwargs). Возвращает время в секундах (float). """ start = time.perf_counter() result = func(*args, **kwargs) end = time.perf_counter() return end - start, result # ========== 2. Многократные замеры с усреднением ========== def run_experiment(func: Callable, args: Tuple, min_runs: int = 5) -> Tuple[float, List[float]]: """ Повторяет замер функции func(*args) минимум min_runs раз. Возвращает (среднее_время, список_всех_замеров). """ times = [] for _ in range(min_runs): elapsed, _ = measure_time(func, *args) times.append(elapsed) avg_time = sum(times) / len(times) return avg_time, times # ========== 3. Тестовые сценарии (заглушки для демонстрации) ========== # Ниже приведены примеры-заглушки для структур данных. # В реальной работе их нужно заменить на реализованные функции. def stub_insert(structure, name, phone): """Заглушка для вставки.""" pass def stub_find(structure, name): """Заглушка для поиска.""" return None def stub_delete(structure, name): """Заглушка для удаления.""" pass def stub_list_all(structure): """Заглушка для получения всех записей.""" return [] # Пример функции, которая вставляет все записи из списка в структуру def insert_all(structure, records, insert_func): """ Выполняет вставку всех записей (name, phone) в structure, используя функцию insert_func(structure, name, phone). """ for name, phone in records: insert_func(structure, name, phone) # Пример замера вставки для конкретной структуры def benchmark_insert(structure_creator, records, insert_func, runs=5): """ Создаёт новую структуру через structure_creator(), затем измеряет время вставки всех записей. """ def _insert_all(): structure = structure_creator() insert_all(structure, records, insert_func) return structure avg_time, all_times = run_experiment(_insert_all, args=(), min_runs=runs) return avg_time, all_times # ========== 4. Пример использования (демонстрация) ========== if __name__ == "__main__": # Фиксируем seed для воспроизводимости random.seed(42) # Генерируем тестовые данные (пункт 1) N = 10000 records_shuffled, records_sorted = generate_test_data(N, duplicate_names_ratio=0.1) # Выбираем 100 случайных имён для поиска (существующих) и 10 несуществующих existing_names = [name for name, _ in records_shuffled[:100]] # первые 100 имён nonexisting_names = [f"None_{i}" for i in range(10)] # Для демонстрации используем заглушки def dummy_creator(): return "dummy_structure" print("=== Демонстрация замера времени (заглушки) ===") avg, times = benchmark_insert(dummy_creator, records_shuffled, stub_insert, runs=3) print(f"Среднее время вставки (заглушка): {avg:.6f} сек") print(f"Все замеры: {times}") # Пример сбора результатов для CSV results = [ ["Структура", "Режим", "Операция", "Время (сек)"], ["LinkedList", "случайный", "вставка", 0.123], # ... реальные данные появятся после реализации структур ] # Сохранение в CS V (раскомментировать при необходимости) # import csv # with open("docs/data/results.csv", "w", newline="") as f: # writer = csv.writer(f) # writer.writerows(results) print("\nГотово. Замеры можно проводить после реализации структур.")