import time import random import csv import sys from linked_list_phonebook import * from hash_table_phonebook import * from bst_phonebook import * sys.setrecursionlimit(100000) def generate_test_data(n=10000): """Генерация тестовых данных""" uniform_records = [(f"User_{i:05d}", f"+7-999-{i:07d}") for i in range(n)] shuffled_records = uniform_records.copy() random.shuffle(shuffled_records) sorted_records = sorted(uniform_records, key=lambda x: x[0]) existing_names = [f"User_{i:05d}" for i in random.sample(range(n), 100)] non_existing_names = [f"None_{i:05d}" for i in range(10)] search_names = existing_names + non_existing_names delete_names = [f"User_{i:05d}" for i in random.sample(range(n), 50)] return { 'shuffled': shuffled_records, 'sorted': sorted_records, 'search_names': search_names, 'delete_names': delete_names } def run_benchmarks(): print("Генерация тестовых данных...") N = 10000 test_data = generate_test_data(N) results = [] structures = [ ('LinkedList', 'll'), ('HashTable', 'ht'), ('BST', 'bst') ] modes = [ ('случайный', test_data['shuffled']), ('отсортированный', test_data['sorted']) ] REPEATS = 5 # Количество повторов for struct_name, struct_type in structures: print(f"\n=== Тестирование {struct_name} ===") for mode_name, records in modes: print(f" Режим: {mode_name}") # Запускаем 5 повторов для каждой комбинации for rep in range(1, REPEATS + 1): print(f" Повтор {rep}/{REPEATS}...") # Создаем структуру и меряем вставку if struct_type == 'll': structure = None start = time.perf_counter() for name, phone in records: structure = ll_insert(structure, name, phone) end = time.perf_counter() insert_time = end - start elif struct_type == 'ht': structure = create_hash_table(5000) start = time.perf_counter() for name, phone in records: ht_insert(structure, name, phone) end = time.perf_counter() insert_time = end - start elif struct_type == 'bst': structure = None start = time.perf_counter() for name, phone in records: structure = bst_insert(structure, name, phone) end = time.perf_counter() insert_time = end - start results.append([struct_name, mode_name, "вставка", insert_time, rep]) # Поиск start = time.perf_counter() for name in test_data['search_names']: if struct_type == 'll': ll_find(structure, name) elif struct_type == 'ht': ht_find(structure, name) elif struct_type == 'bst': bst_find(structure, name) end = time.perf_counter() find_time = end - start results.append([struct_name, mode_name, "поиск", find_time, rep]) # Удаление start = time.perf_counter() for name in test_data['delete_names']: if struct_type == 'll': structure = ll_delete(structure, name) elif struct_type == 'ht': ht_delete(structure, name) elif struct_type == 'bst': structure = bst_delete(structure, name) end = time.perf_counter() delete_time = end - start results.append([struct_name, mode_name, "удаление", delete_time, rep]) # Сохраняем в CSV с колонкой "Повтор" with open('docs/data/results.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['Структура', 'Режим', 'Операция', 'Время (сек)', 'Повтор']) writer.writerows(results) # Подсчет средних значений print("\n" + "="*70) print("СРЕДНИЕ ЗНАЧЕНИЯ (по 5 повторам)") print("="*70) # Собираем данные для средних from collections import defaultdict avg_data = defaultdict(list) for row in results: key = (row[0], row[1], row[2]) avg_data[key].append(row[3]) print(f"{'Структура':15} {'Режим':13} {'Операция':10} {'Среднее время':>12}") print("-"*55) for (struct, mode, op), times in avg_data.items(): avg_time = sum(times) / len(times) print(f"{struct:15} {mode:13} {op:10} {avg_time:12.6f}") print(f"\nВсе замеры (5 повторов) сохранены в docs/data/results.csv") if __name__ == "__main__": random.seed(42) run_benchmarks()