diff --git a/lomakinae/docs/data/01/src/bench.py b/lomakinae/docs/data/01/src/bench.py new file mode 100644 index 0000000..f81e0a4 --- /dev/null +++ b/lomakinae/docs/data/01/src/bench.py @@ -0,0 +1,72 @@ +import time +from ll import ll_insert, ll_find, ll_delete +from ht import ht_new, ht_insert, ht_find, ht_delete +from bst import bst_insert, bst_find, bst_delete + + +def _build_ll(records): + head = None + for name, phone in records: + head = ll_insert(head, name, phone) + return head + + +def _build_ht(records): + buckets = ht_new() + for name, phone in records: + ht_insert(buckets, name, phone) + return buckets + + +def _build_bst(records): + root = None + for name, phone in records: + root = bst_insert(root, name, phone) + return root + + +def _time_insert(build_fn, records): + start = time.perf_counter() + structure = build_fn(records) + end = time.perf_counter() + elapsed = end - start + return elapsed, structure + + +def _time_find(find_fn, structure, names): + start = time.perf_counter() + for name in names: + find_fn(structure, name) + end = time.perf_counter() + elapsed = end - start + return elapsed + + +def _time_delete(delete_fn, structure, names): + start = time.perf_counter() + for name in names: + result = delete_fn(structure, name) + if result is not None: + structure = result + end = time.perf_counter() + elapsed = end - start + return elapsed, structure + + +def run_once(records, search_names, delete_names): + results = [] + + structures = { + 'LinkedList': (_build_ll, ll_find, ll_delete), + 'HashTable': (_build_ht, ht_find, ht_delete), + 'BST': (_build_bst, bst_find, bst_delete), + } + + for label, (build_fn, find_fn, delete_fn) in structures.items(): + t_insert, structure = _time_insert(build_fn, records) + t_find = _time_find(find_fn, structure, search_names) + t_delete, structure = _time_delete(delete_fn, structure, delete_names) + + results.append((label, t_insert, t_find, t_delete)) + + return results diff --git a/lomakinae/docs/data/01/src/experiment.py b/lomakinae/docs/data/01/src/experiment.py new file mode 100644 index 0000000..776bd3d --- /dev/null +++ b/lomakinae/docs/data/01/src/experiment.py @@ -0,0 +1,53 @@ +import csv +import random +import sys + +from generator import generate_records, shuffle_records, sort_records, sample_existing, sample_nonexistent +from bench import run_once + +N = 10000 +RUNS = 5 +SEARCH_K = 100 +SEARCH_MISSING_K = 10 +DELETE_K = 50 +sys.setrecursionlimit(15000) + + +def run_experiment(records, mode): + search_names = sample_existing(records, SEARCH_K) + sample_nonexistent(SEARCH_MISSING_K) + delete_names = sample_existing(records, DELETE_K) + + all_rows = [] + + for run_i in range(1, RUNS + 1): + print(f" [{mode}] run {run_i}/{RUNS} ...") + run_results = run_once(records, search_names, delete_names) + for label, t_insert, t_find, t_delete in run_results: + all_rows.append([label, mode, 'insert', run_i, round(t_insert, 6)]) + all_rows.append([label, mode, 'find', run_i, round(t_find, 6)]) + all_rows.append([label, mode, 'delete', run_i, round(t_delete, 6)]) + + return all_rows + + +if __name__ == '__main__': + random.seed(52) + + records_base = generate_records(N) + records_shuffled = shuffle_records(records_base) + records_sorted = sort_records(records_base) + + rows = [] + rows += run_experiment(records_shuffled, 'shuffled') + rows += run_experiment(records_sorted, 'sorted') + + header = ['structure', 'mode', 'operation', 'run', 'time_sec'] + output_path = 'results.csv' + + with open(output_path, 'w', newline='') as f: + writer = csv.writer(f) + writer.writerow(header) + writer.writerows(rows) + + print(f"Done. Results saved to {output_path}") + print(f"Total rows: {len(rows)}") diff --git a/lomakinae/docs/data/01/src/results.csv b/lomakinae/docs/data/01/src/results.csv new file mode 100644 index 0000000..f536eb8 --- /dev/null +++ b/lomakinae/docs/data/01/src/results.csv @@ -0,0 +1,91 @@ +structure,mode,operation,run,time_sec +LinkedList,shuffled,insert,1,3.146608 +LinkedList,shuffled,find,1,0.038634 +LinkedList,shuffled,delete,1,0.02447 +HashTable,shuffled,insert,1,0.032404 +HashTable,shuffled,find,1,0.000543 +HashTable,shuffled,delete,1,0.000314 +BST,shuffled,insert,1,0.024271 +BST,shuffled,find,1,0.000238 +BST,shuffled,delete,1,0.00014 +LinkedList,shuffled,insert,2,3.360195 +LinkedList,shuffled,find,2,0.038226 +LinkedList,shuffled,delete,2,0.026174 +HashTable,shuffled,insert,2,0.031514 +HashTable,shuffled,find,2,0.000531 +HashTable,shuffled,delete,2,0.000297 +BST,shuffled,insert,2,0.025051 +BST,shuffled,find,2,0.000227 +BST,shuffled,delete,2,0.000134 +LinkedList,shuffled,insert,3,3.298482 +LinkedList,shuffled,find,3,0.038049 +LinkedList,shuffled,delete,3,0.026032 +HashTable,shuffled,insert,3,0.030625 +HashTable,shuffled,find,3,0.000472 +HashTable,shuffled,delete,3,0.000286 +BST,shuffled,insert,3,0.023956 +BST,shuffled,find,3,0.000218 +BST,shuffled,delete,3,0.000128 +LinkedList,shuffled,insert,4,3.342319 +LinkedList,shuffled,find,4,0.038768 +LinkedList,shuffled,delete,4,0.02615 +HashTable,shuffled,insert,4,0.03061 +HashTable,shuffled,find,4,0.000462 +HashTable,shuffled,delete,4,0.000286 +BST,shuffled,insert,4,0.023686 +BST,shuffled,find,4,0.000213 +BST,shuffled,delete,4,0.000132 +LinkedList,shuffled,insert,5,3.376158 +LinkedList,shuffled,find,5,0.039137 +LinkedList,shuffled,delete,5,0.026008 +HashTable,shuffled,insert,5,0.030944 +HashTable,shuffled,find,5,0.000488 +HashTable,shuffled,delete,5,0.000291 +BST,shuffled,insert,5,0.022971 +BST,shuffled,find,5,0.000214 +BST,shuffled,delete,5,0.000135 +LinkedList,sorted,insert,1,3.226524 +LinkedList,sorted,find,1,0.03718 +LinkedList,sorted,delete,1,0.0253 +HashTable,sorted,insert,1,0.030623 +HashTable,sorted,find,1,0.000491 +HashTable,sorted,delete,1,0.000274 +BST,sorted,insert,1,11.323304 +BST,sorted,find,1,0.096899 +BST,sorted,delete,1,0.053995 +LinkedList,sorted,insert,2,3.3209 +LinkedList,sorted,find,2,0.037479 +LinkedList,sorted,delete,2,0.024458 +HashTable,sorted,insert,2,0.030579 +HashTable,sorted,find,2,0.000491 +HashTable,sorted,delete,2,0.000274 +BST,sorted,insert,2,11.633176 +BST,sorted,find,2,0.098893 +BST,sorted,delete,2,0.055018 +LinkedList,sorted,insert,3,3.248168 +LinkedList,sorted,find,3,0.036984 +LinkedList,sorted,delete,3,0.025185 +HashTable,sorted,insert,3,0.03095 +HashTable,sorted,find,3,0.000482 +HashTable,sorted,delete,3,0.000276 +BST,sorted,insert,3,11.457209 +BST,sorted,find,3,0.098241 +BST,sorted,delete,3,0.054005 +LinkedList,sorted,insert,4,3.175529 +LinkedList,sorted,find,4,0.036891 +LinkedList,sorted,delete,4,0.025014 +HashTable,sorted,insert,4,0.030979 +HashTable,sorted,find,4,0.000505 +HashTable,sorted,delete,4,0.000284 +BST,sorted,insert,4,11.49292 +BST,sorted,find,4,0.099439 +BST,sorted,delete,4,0.055095 +LinkedList,sorted,insert,5,3.228069 +LinkedList,sorted,find,5,0.03687 +LinkedList,sorted,delete,5,0.025142 +HashTable,sorted,insert,5,0.031015 +HashTable,sorted,find,5,0.000505 +HashTable,sorted,delete,5,0.00028 +BST,sorted,insert,5,11.420234 +BST,sorted,find,5,0.09862 +BST,sorted,delete,5,0.054981