286 lines
8.5 KiB
Python
286 lines
8.5 KiB
Python
import random
|
||
import time
|
||
import csv
|
||
import os
|
||
from phonebook import *
|
||
|
||
def generate_test_data(n=10000):
|
||
|
||
records = [(f"User_{i:05d}", f"+7-999-{i:07d}") for i in range(n)]
|
||
|
||
records_shuffled = records.copy()
|
||
random.shuffle(records_shuffled)
|
||
|
||
records_sorted = sorted(records, key=lambda x: x[0])
|
||
|
||
return records_shuffled, records_sorted
|
||
|
||
def get_random_names(records, n=100):
|
||
return[name for name, _ in random.sample(records, min(n, len(records)))]
|
||
|
||
def run_linked_experiments(records, mode_name):
|
||
|
||
print(f"\n связный список ({mode_name}):")
|
||
|
||
print("вставка 10000 записей:")
|
||
|
||
insert_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
head = None
|
||
for name, phone in records:
|
||
head = ll_insert(head, name, phone)
|
||
end = time.perf_counter()
|
||
insert_times.append(end - start)
|
||
print(f"Вставка {run+1}/5: {insert_times[-1]:.6f} сек")
|
||
|
||
avg_insert = sum(insert_times) / 5
|
||
print(f"среднее: {avg_insert:.6f} сек")
|
||
|
||
print("поиск 110 записей:")
|
||
|
||
exist_names = get_random_names(records, 100)
|
||
non_exist_names = [f"None_{i}" for i in range(10)]
|
||
|
||
find_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
|
||
for name in exist_names:
|
||
ll_find(head, name)
|
||
for name in non_exist_names:
|
||
ll_find(head, name)
|
||
|
||
end = time.perf_counter()
|
||
find_times.append(end - start)
|
||
print(f"поиск {run+1}/5: {find_times[-1]:.6f} сек")
|
||
|
||
avg_find = sum(find_times) / 5
|
||
print(f"среднее: {avg_find:.6f} сек")
|
||
|
||
print("удаление 50 случайных записей:")
|
||
|
||
to_delete = get_random_names(records,50)
|
||
|
||
delete_times = []
|
||
for run in range(5):
|
||
current_head = head
|
||
start = time.perf_counter()
|
||
for name in to_delete:
|
||
current_head = ll_delete(current_head, name)
|
||
end = time.perf_counter()
|
||
delete_times.append(end - start)
|
||
print(f"удаление {run+1}/5: {delete_times[-1]:.6f} сек")
|
||
|
||
avg_delete = sum(delete_times) / 5
|
||
print(f"среднее: {avg_delete:.6f} сек")
|
||
|
||
return{
|
||
'structure': 'LinkedList',
|
||
'mode': mode_name,
|
||
'insert_avg': avg_insert,
|
||
'insert_all': insert_times,
|
||
'find_avg': avg_find,
|
||
'find_all': find_times,
|
||
'delete_avg': avg_delete,
|
||
'delete_all': delete_times
|
||
}
|
||
|
||
def run_hash_experiments(records, mode_name):
|
||
|
||
print(f"хеш-таблица({mode_name})")
|
||
|
||
print("вставка 10000 записей:")
|
||
|
||
insert_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
|
||
buckets = ht_create(1000)
|
||
for name, phone in records:
|
||
buckets = ht_insert(buckets, name, phone)
|
||
|
||
end = time.perf_counter()
|
||
insert_times.append(end - start)
|
||
print(f"Вставка {run+1}/5: {insert_times[-1]:.6f} сек")
|
||
|
||
avg_insert = sum(insert_times) / 5
|
||
print(f"среднее: {avg_insert:.6f} сек")
|
||
|
||
print("поиск 110 записей:")
|
||
|
||
exist_names = get_random_names(records, 100)
|
||
non_exist_names = [f"None_{i}" for i in range(10)]
|
||
|
||
find_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
|
||
for name in exist_names:
|
||
ht_find(buckets, name)
|
||
for name in non_exist_names:
|
||
ht_find(buckets, name)
|
||
|
||
end = time.perf_counter()
|
||
find_times.append(end - start)
|
||
print(f"поиск {run+1}/5: {find_times[-1]:.6f} сек")
|
||
|
||
avg_find = sum(find_times) / 5
|
||
print(f"среднее: {avg_find:.6f} сек")
|
||
|
||
print("удаление 50 случайных записей:")
|
||
|
||
to_delete = get_random_names(records,50)
|
||
|
||
delete_times = []
|
||
for run in range(5):
|
||
current_buckets = buckets.copy()
|
||
start = time.perf_counter()
|
||
for name in to_delete:
|
||
current_buckets = ht_delete(current_buckets, name)
|
||
end = time.perf_counter()
|
||
delete_times.append(end - start)
|
||
print(f"удаление {run+1}/5: {delete_times[-1]:.6f} сек")
|
||
|
||
avg_delete = sum(delete_times) / 5
|
||
print(f"среднее: {avg_delete:.6f} сек")
|
||
|
||
return{
|
||
'structure': 'HashTable',
|
||
'mode': mode_name,
|
||
'insert_avg': avg_insert,
|
||
'insert_all': insert_times,
|
||
'find_avg': avg_find,
|
||
'find_all': find_times,
|
||
'delete_avg': avg_delete,
|
||
'delete_all': delete_times
|
||
}
|
||
|
||
def run_bst_experiments(records, mode_name):
|
||
|
||
print(f"двоичное дерево({mode_name})")
|
||
|
||
print("вставка 10000 записей:")
|
||
|
||
insert_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
|
||
root = None
|
||
for name, phone in records:
|
||
root = bst_insert(root, name, phone)
|
||
|
||
end = time.perf_counter()
|
||
insert_times.append(end - start)
|
||
print(f"Вставка {run+1}/5: {insert_times[-1]:.6f} сек")
|
||
|
||
avg_insert = sum(insert_times) / 5
|
||
print(f"среднее: {avg_insert:.6f} сек")
|
||
|
||
print("поиск 110 записей:")
|
||
|
||
exist_names = get_random_names(records, 100)
|
||
non_exist_names = [f"None_{i}" for i in range(10)]
|
||
|
||
find_times = []
|
||
for run in range(5):
|
||
start = time.perf_counter()
|
||
|
||
for name in exist_names:
|
||
bst_find(root, name)
|
||
for name in non_exist_names:
|
||
bst_find(root, name)
|
||
|
||
end = time.perf_counter()
|
||
find_times.append(end - start)
|
||
print(f"поиск {run+1}/5: {find_times[-1]:.6f} сек")
|
||
|
||
avg_find = sum(find_times) / 5
|
||
print(f"среднее: {avg_find:.6f} сек")
|
||
|
||
print("удаление 50 случайных записей:")
|
||
|
||
to_delete = get_random_names(records,50)
|
||
|
||
delete_times = []
|
||
for run in range(5):
|
||
current_root = root
|
||
start = time.perf_counter()
|
||
for name in to_delete:
|
||
current_root = bst_delete(current_root, name)
|
||
end = time.perf_counter()
|
||
delete_times.append(end - start)
|
||
print(f"удаление {run+1}/5: {delete_times[-1]:.6f} сек")
|
||
|
||
avg_delete = sum(delete_times) / 5
|
||
print(f"среднее: {avg_delete:.6f} сек")
|
||
|
||
return{
|
||
'structure': 'BST',
|
||
'mode': mode_name,
|
||
'insert_avg': avg_insert,
|
||
'insert_all': insert_times,
|
||
'find_avg': avg_find,
|
||
'find_all': find_times,
|
||
'delete_avg': avg_delete,
|
||
'delete_all': delete_times
|
||
}
|
||
def save_result_to_csv(all_results):
|
||
|
||
os.makedirs("docs/data", exist_ok=True)
|
||
|
||
csv_rows = []
|
||
|
||
csv_rows.append(["Структура", "Режим", "Операция", "Номер_замера", "Время(сек)"])
|
||
|
||
for res in all_results:
|
||
struct = res['structure']
|
||
mode = res['mode']
|
||
|
||
for i, t in enumerate(res['insert_all']):
|
||
csv_rows.append([struct, mode, "вставка", i+1, t])
|
||
|
||
csv_rows.append([struct, "вставка", "среднее", res['insert_avg']])
|
||
|
||
for i, t in enumerate(res['find_all']):
|
||
csv_rows.append([struct, mode, "поиск", i+1, t])
|
||
|
||
csv_rows.append([struct, "поиск", "среднее", res['find_avg']])
|
||
|
||
for i, t in enumerate(res['delete_all']):
|
||
csv_rows.append([struct, mode, "удаление", i+1, t])
|
||
|
||
csv_rows.append([struct, "удаление", "среднее", res['delete_avg']])
|
||
|
||
with open("docs/data/resurts.csv", "w", newline="", encoding="utf-8") as f:
|
||
writer = csv.writer(f)
|
||
writer.writerow(csv_rows)
|
||
print(f"\nрезультаты сохранены")
|
||
|
||
def main():
|
||
print("эксперименты по замеру производительности")
|
||
|
||
records_shuffled, records_sorted = generate_test_data(10000)
|
||
|
||
all_results = []
|
||
|
||
print("режим: случайный порядок")
|
||
|
||
all_results.append(run_linked_experiments(records_shuffled, "случайный"))
|
||
all_results.append(run_hash_experiments(records_shuffled, "случайный"))
|
||
all_results.append(run_bst_experiments(records_shuffled, "случайный"))
|
||
|
||
print("режим: отсортированный порядок")
|
||
|
||
all_results.append(run_linked_experiments(records_sorted, "отсортированный"))
|
||
all_results.append(run_hash_experiments(records_sorted, "отсортированный"))
|
||
all_results.append(run_bst_experiments(records_sorted, "отсортированный"))
|
||
|
||
save_result_to_csv(all_results)
|
||
|
||
if __name__== "__main__":
|
||
main()
|
||
|
||
|
||
|