forked from UNN/2026-rff_mp
Удалить experiment.py
This commit is contained in:
parent
ad50ed566b
commit
d5b340d2d3
132
experiment.py
132
experiment.py
|
|
@ -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}")
|
||||
Loading…
Reference in New Issue
Block a user