[1] файл для запуска измерений
This commit is contained in:
parent
30d416cfac
commit
980da05ed5
210
shalovsa/lab1/docs/data/laba.py
Normal file
210
shalovsa/lab1/docs/data/laba.py
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
|
||||||
|
from phone_book import (
|
||||||
|
ll_insert, ll_find, ll_delete, ll_list_all,
|
||||||
|
ht_make, ht_insert, ht_find, ht_delete, ht_list_all,
|
||||||
|
bst_insert, bst_find, bst_delete, bst_list_all,
|
||||||
|
)
|
||||||
|
|
||||||
|
N = 10_000
|
||||||
|
REPEATS = 5
|
||||||
|
SEARCH_COUNT = 110
|
||||||
|
DELETE_COUNT = 50
|
||||||
|
HT_SIZE = 256
|
||||||
|
|
||||||
|
RANDOM_SEED = 42
|
||||||
|
random.seed(RANDOM_SEED)
|
||||||
|
|
||||||
|
OUTPUT_DIR = os.path.dirname(__file__)
|
||||||
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||||
|
CSV_PATH = os.path.join(OUTPUT_DIR, 'results.csv')
|
||||||
|
|
||||||
|
def generate_records(n):
|
||||||
|
records = [(f"User_{i:05d}", f"+7{random.randint(1000000000, 9999999999)}")
|
||||||
|
for i in range(n)]
|
||||||
|
return records
|
||||||
|
|
||||||
|
|
||||||
|
records_base = generate_records(N)
|
||||||
|
|
||||||
|
records_shuffled = records_base[:]
|
||||||
|
random.shuffle(records_shuffled)
|
||||||
|
|
||||||
|
records_sorted = sorted(records_base, key=lambda x: x[0])
|
||||||
|
|
||||||
|
existing_names = [r[0] for r in random.sample(records_base, 100)]
|
||||||
|
missing_names = [f"None_{i}" for i in range(10)]
|
||||||
|
search_names = existing_names + missing_names
|
||||||
|
|
||||||
|
delete_names = [r[0] for r in random.sample(records_base, DELETE_COUNT)]
|
||||||
|
|
||||||
|
def measure(func, *args, **kwargs):
|
||||||
|
start = time.perf_counter()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
end = time.perf_counter()
|
||||||
|
return end - start, result
|
||||||
|
|
||||||
|
def bench_linked_list(records, mode_label):
|
||||||
|
times = {'insert': [], 'find': [], 'delete': []}
|
||||||
|
|
||||||
|
for _ in range(REPEATS):
|
||||||
|
head = None
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name, phone in records:
|
||||||
|
head = ll_insert(head, name, phone)
|
||||||
|
times['insert'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in search_names:
|
||||||
|
ll_find(head, name)
|
||||||
|
times['find'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in delete_names:
|
||||||
|
head = ll_delete(head, name)
|
||||||
|
times['delete'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
return times
|
||||||
|
|
||||||
|
|
||||||
|
def bench_hash_table(records, mode_label):
|
||||||
|
times = {'insert': [], 'find': [], 'delete': []}
|
||||||
|
|
||||||
|
for _ in range(REPEATS):
|
||||||
|
buckets = ht_make(HT_SIZE)
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name, phone in records:
|
||||||
|
ht_insert(buckets, name, phone)
|
||||||
|
times['insert'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in search_names:
|
||||||
|
ht_find(buckets, name)
|
||||||
|
times['find'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in delete_names:
|
||||||
|
ht_delete(buckets, name)
|
||||||
|
times['delete'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
return times
|
||||||
|
|
||||||
|
|
||||||
|
def bench_bst(records, mode_label):
|
||||||
|
times = {'insert': [], 'find': [], 'delete': []}
|
||||||
|
|
||||||
|
for _ in range(REPEATS):
|
||||||
|
root = None
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name, phone in records:
|
||||||
|
root = bst_insert(root, name, phone)
|
||||||
|
times['insert'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in search_names:
|
||||||
|
bst_find(root, name)
|
||||||
|
times['find'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
for name in delete_names:
|
||||||
|
root = bst_delete(root, name)
|
||||||
|
times['delete'].append(time.perf_counter() - t_start)
|
||||||
|
|
||||||
|
return times
|
||||||
|
|
||||||
|
def avg(lst):
|
||||||
|
return sum(lst) / len(lst)
|
||||||
|
|
||||||
|
|
||||||
|
def run_all():
|
||||||
|
print(f"Запуск: N={N}, повторений={REPEATS}\n")
|
||||||
|
print(f"{'Структура':<15} {'Режим':<12} {'Операция':<10} "
|
||||||
|
f"{'Среднее (с)':<14} {'Все замеры'}")
|
||||||
|
print("-" * 80)
|
||||||
|
|
||||||
|
all_results = [["Структура", "Режим", "Операция", "Среднее (с)"] +
|
||||||
|
[f"Замер_{i+1}" for i in range(REPEATS)]]
|
||||||
|
|
||||||
|
datasets = [
|
||||||
|
(records_shuffled, "случайный"),
|
||||||
|
(records_sorted, "сортированный"),
|
||||||
|
]
|
||||||
|
|
||||||
|
benchmarks = [
|
||||||
|
("LinkedList", bench_linked_list),
|
||||||
|
("HashTable", bench_hash_table),
|
||||||
|
("BST", bench_bst),
|
||||||
|
]
|
||||||
|
|
||||||
|
for ds_records, ds_mode in datasets:
|
||||||
|
for struct_name, bench_func in benchmarks:
|
||||||
|
print(f"\n [{struct_name}] режим: {ds_mode}")
|
||||||
|
if struct_name == "BST" and ds_mode == "сортированный":
|
||||||
|
import sys
|
||||||
|
sys.setrecursionlimit(50_000)
|
||||||
|
|
||||||
|
times = bench_func(ds_records, ds_mode)
|
||||||
|
|
||||||
|
for op, op_times in times.items():
|
||||||
|
mean = avg(op_times)
|
||||||
|
row = [struct_name, ds_mode, op, f"{mean:.6f}"] + \
|
||||||
|
[f"{t:.6f}" for t in op_times]
|
||||||
|
all_results.append(row)
|
||||||
|
|
||||||
|
print(f" {op:<10} среднее={mean:.6f}с "
|
||||||
|
f"замеры={[f'{t:.4f}' for t in op_times]}")
|
||||||
|
|
||||||
|
with open(CSV_PATH, 'w', newline='', encoding='utf-8') as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerows(all_results)
|
||||||
|
|
||||||
|
print(f"\n✅ Результаты сохранены в: {CSV_PATH}")
|
||||||
|
return all_results
|
||||||
|
|
||||||
|
def smoke_test():
|
||||||
|
print("=== Smoke Test ===\n")
|
||||||
|
|
||||||
|
test_data = [("Alice", "111"), ("Bob", "222"), ("Charlie", "333")]
|
||||||
|
|
||||||
|
head = None
|
||||||
|
for name, phone in test_data:
|
||||||
|
head = ll_insert(head, name, phone)
|
||||||
|
assert ll_find(head, "Alice") == "111"
|
||||||
|
assert ll_find(head, "Bob") == "222"
|
||||||
|
assert ll_find(head, "Nobody") is None
|
||||||
|
head = ll_delete(head, "Bob")
|
||||||
|
assert ll_find(head, "Bob") is None
|
||||||
|
sorted_ll = ll_list_all(head)
|
||||||
|
assert sorted_ll == [("Alice", "111"), ("Charlie", "333")]
|
||||||
|
print("✅ LinkedList — OK")
|
||||||
|
|
||||||
|
buckets = ht_make(16)
|
||||||
|
for name, phone in test_data:
|
||||||
|
ht_insert(buckets, name, phone)
|
||||||
|
assert ht_find(buckets, "Charlie") == "333"
|
||||||
|
assert ht_find(buckets, "Nobody") is None
|
||||||
|
ht_delete(buckets, "Alice")
|
||||||
|
assert ht_find(buckets, "Alice") is None
|
||||||
|
sorted_ht = ht_list_all(buckets)
|
||||||
|
assert sorted_ht == [("Bob", "222"), ("Charlie", "333")]
|
||||||
|
print("✅ HashTable — OK")
|
||||||
|
|
||||||
|
root = None
|
||||||
|
for name, phone in test_data:
|
||||||
|
root = bst_insert(root, name, phone)
|
||||||
|
assert bst_find(root, "Alice") == "111"
|
||||||
|
assert bst_find(root, "Nobody") is None
|
||||||
|
root = bst_delete(root, "Alice")
|
||||||
|
assert bst_find(root, "Alice") is None
|
||||||
|
sorted_bst = bst_list_all(root)
|
||||||
|
assert sorted_bst == [("Bob", "222"), ("Charlie", "333")]
|
||||||
|
print("✅ BST — OK")
|
||||||
|
|
||||||
|
print("\nВсе тесты пройдены!\n")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
smoke_test()
|
||||||
|
results = run_all()
|
||||||
Loading…
Reference in New Issue
Block a user