2026-rff_mp/pogodinda/lab1/benchmark.py

144 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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()