diff --git a/src/measure_time.py b/src/measure_time.py new file mode 100644 index 0000000..f84fe2a --- /dev/null +++ b/src/measure_time.py @@ -0,0 +1,129 @@ +""" +Экспериментальная часть. Пункт 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Готово. Замеры можно проводить после реализации структур.") \ No newline at end of file