[2] final #382

Merged
git_admin merged 9 commits from :4 into develop 2026-09-05 06:37:37 +00:00
Showing only changes of commit d5b340d2d3 - Show all commits

View File

@ -1,132 +0,0 @@
"""Экспериментальное сравнение структур данных."""
import argparse
import csv
import random
from pathlib import Path
from statistics import mean
from time import perf_counter
from phonebook import (
bst_delete, bst_find, bst_insert,
ht_delete, ht_find, ht_insert,
ll_delete, ll_find, ll_insert,
)
def generate_records(size):
return [(f"User_{index:05d}", f"+7{index:010d}") for index in range(size)]
def measure_once(structure, records, existing_names, missing_names, deleted_names, bucket_count):
started = perf_counter()
if structure == "LinkedList":
data = None
for name, phone in records:
data = ll_insert(data, name, phone)
insert_time = perf_counter() - started
started = perf_counter()
for name in existing_names + missing_names:
ll_find(data, name)
find_time = perf_counter() - started
started = perf_counter()
for name in deleted_names:
data = ll_delete(data, name)
delete_time = perf_counter() - started
elif structure == "HashTable":
data = [None] * bucket_count
for name, phone in records:
ht_insert(data, name, phone)
insert_time = perf_counter() - started
started = perf_counter()
for name in existing_names + missing_names:
ht_find(data, name)
find_time = perf_counter() - started
started = perf_counter()
for name in deleted_names:
ht_delete(data, name)
delete_time = perf_counter() - started
else:
data = None
for name, phone in records:
data = bst_insert(data, name, phone)
insert_time = perf_counter() - started
started = perf_counter()
for name in existing_names + missing_names:
bst_find(data, name)
find_time = perf_counter() - started
started = perf_counter()
for name in deleted_names:
data = bst_delete(data, name)
delete_time = perf_counter() - started
return {"insert": insert_time, "find_110": find_time, "delete_50": delete_time}
def run_experiment(size=3000, repeats=5, seed=2026, output_dir="docs/data"):
rng = random.Random(seed)
sorted_records = generate_records(size)
shuffled_records = sorted_records.copy()
rng.shuffle(shuffled_records)
modes = {"shuffled": shuffled_records, "sorted": sorted_records}
rows = []
for mode, records in modes.items():
names = [record[0] for record in records]
test_cases = []
for run in range(1, repeats + 1):
test_cases.append((
run,
rng.sample(names, min(100, size)),
[f"None_{index}" for index in range(10)],
rng.sample(names, min(50, size)),
))
for structure in ("LinkedList", "HashTable", "BST"):
for run, existing, missing, deleted in test_cases:
timings = measure_once(structure, records, existing, missing, deleted, max(17, size * 2 + 1))
for operation, elapsed in timings.items():
rows.append({
"structure": structure,
"mode": mode,
"operation": operation,
"run": run,
"time_seconds": elapsed,
})
output = Path(output_dir)
output.mkdir(parents=True, exist_ok=True)
raw_path = output / "results_raw.csv"
with raw_path.open("w", newline="", encoding="utf-8-sig") as file:
writer = csv.DictWriter(file, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
groups = {}
for row in rows:
key = (row["structure"], row["mode"], row["operation"])
groups.setdefault(key, []).append(row["time_seconds"])
summary = [
{"structure": key[0], "mode": key[1], "operation": key[2], "mean_seconds": mean(values)}
for key, values in groups.items()
]
summary_path = output / "results_summary.csv"
with summary_path.open("w", newline="", encoding="utf-8-sig") as file:
writer = csv.DictWriter(file, fieldnames=summary[0].keys())
writer.writeheader()
writer.writerows(summary)
return raw_path, summary_path
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Сравнение структур телефонного справочника")
parser.add_argument("--size", type=int, default=3000)
parser.add_argument("--repeats", type=int, default=5)
args = parser.parse_args()
raw, summary = run_experiment(args.size, args.repeats)
print(f"Полные замеры: {raw}\nСредние значения: {summary}")