собрала отдельные папки для лаб
This commit is contained in:
parent
106ea57b17
commit
0b2b19a2ca
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
282
victorovaas/lab1/experiments.py
Normal file
282
victorovaas/lab1/experiments.py
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
from lab1.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"\n хеш-таблица({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"\n двоичное дерево({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_results_to_csv(all_results):
|
||||||
|
|
||||||
|
os.makedirs("docs/data", exist_ok=True)
|
||||||
|
|
||||||
|
with open("docs/data/results.csv", "w", encoding="utf-8") as f:
|
||||||
|
|
||||||
|
f.write("Структура, Режим, Операция, Замер, Время (сек)\n")
|
||||||
|
|
||||||
|
for res in all_results:
|
||||||
|
struct = res['structure']
|
||||||
|
mode = res['mode']
|
||||||
|
|
||||||
|
|
||||||
|
for i, t in enumerate(res['insert_all']):
|
||||||
|
f.write(f"{struct},{mode},вставка,{i+1},{t}\n")
|
||||||
|
f.write(f"{struct},{mode},вставка,среднее,{res['insert_avg']}\n")
|
||||||
|
|
||||||
|
|
||||||
|
for i, t in enumerate(res['find_all']):
|
||||||
|
f.write(f"{struct},{mode},поиск,{i+1},{t}\n")
|
||||||
|
f.write(f"{struct},{mode},поиск,среднее,{res['find_avg']}\n")
|
||||||
|
|
||||||
|
|
||||||
|
for i, t in enumerate(res['delete_all']):
|
||||||
|
f.write(f"{struct},{mode},удаление,{i+1},{t}\n")
|
||||||
|
f.write(f"{struct},{mode},удаление,среднее,{res['delete_avg']}\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_results_to_csv(all_results)
|
||||||
|
|
||||||
|
if __name__== "__main__":
|
||||||
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
123
victorovaas/lab1/make_graphs.py
Normal file
123
victorovaas/lab1/make_graphs.py
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
os.makedirs('docs/data', exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
structures = ['LinkedList', 'HashTable', 'BST']
|
||||||
|
|
||||||
|
random_insert = [0.0037545, 0.015088, 0.026280]
|
||||||
|
sorted_insert = [0.0017544, 0.011369, 4.930788]
|
||||||
|
|
||||||
|
random_search = [0.00000962, 0.0001646, 0.0002592]
|
||||||
|
sorted_search = [0.00000858, 0.00014016, 0.047126]
|
||||||
|
|
||||||
|
random_delete = [0.0000079, 0.00009824, 0.00016984]
|
||||||
|
sorted_delete = [0.00000294, 0.00005878, 0.023013]
|
||||||
|
|
||||||
|
x = np.arange(len(structures))
|
||||||
|
width = 0.35
|
||||||
|
|
||||||
|
#график вставка
|
||||||
|
fig, ax = plt.subplots(figsize=(12, 7))
|
||||||
|
|
||||||
|
bars1 = ax.bar(x - width/2, random_insert, width, label='Случайный порядок', color='#3498db')
|
||||||
|
bars2 = ax.bar(x + width/2, sorted_insert, width, label='Отсортированный порядок', color='#e74c3c')
|
||||||
|
|
||||||
|
|
||||||
|
for bar in bars1:
|
||||||
|
height = bar.get_height()
|
||||||
|
ax.annotate(f'{height:.4f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
|
||||||
|
for bar in bars2:
|
||||||
|
height = bar.get_height()
|
||||||
|
if height < 1:
|
||||||
|
ax.annotate(f'{height:.4f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
else:
|
||||||
|
ax.annotate(f'{height:.1f} сек', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 5), textcoords="offset points", ha='center', va='bottom', fontsize=10, fontweight='bold')
|
||||||
|
|
||||||
|
ax.set_ylabel('Время (сек)', fontsize=12)
|
||||||
|
ax.set_title('Время вставки 10000 записей', fontsize=14, fontweight='bold')
|
||||||
|
ax.set_xticks(x)
|
||||||
|
ax.set_xticklabels(structures, fontsize=11)
|
||||||
|
ax.legend(fontsize=11)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
ax.grid(True, alpha=0.3, axis='y')
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('docs/data/graph_insert.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
# график поиск
|
||||||
|
fig, ax = plt.subplots(figsize=(12, 7))
|
||||||
|
|
||||||
|
bars1 = ax.bar(x - width/2, random_search, width, label='Случайный порядок', color='#3498db')
|
||||||
|
bars2 = ax.bar(x + width/2, sorted_search, width, label='Отсортированный порядок', color='#e74c3c')
|
||||||
|
|
||||||
|
for bar in bars1:
|
||||||
|
height = bar.get_height()
|
||||||
|
ax.annotate(f'{height:.6f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
|
||||||
|
for bar in bars2:
|
||||||
|
height = bar.get_height()
|
||||||
|
if height < 0.01:
|
||||||
|
ax.annotate(f'{height:.6f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
else:
|
||||||
|
ax.annotate(f'{height:.4f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
|
||||||
|
ax.set_ylabel('Время (сек)', fontsize=12)
|
||||||
|
ax.set_title('Время поиска 110 записей', fontsize=14, fontweight='bold')
|
||||||
|
ax.set_xticks(x)
|
||||||
|
ax.set_xticklabels(structures, fontsize=11)
|
||||||
|
ax.legend(fontsize=11)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
ax.grid(True, alpha=0.3, axis='y')
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('docs/data/graph_search.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
|
# график удаление
|
||||||
|
fig, ax = plt.subplots(figsize=(12, 7))
|
||||||
|
|
||||||
|
bars1 = ax.bar(x - width/2, random_delete, width, label='Случайный порядок', color='#3498db')
|
||||||
|
bars2 = ax.bar(x + width/2, sorted_delete, width, label='Отсортированный порядок', color='#e74c3c')
|
||||||
|
|
||||||
|
for bar in bars1:
|
||||||
|
height = bar.get_height()
|
||||||
|
ax.annotate(f'{height:.6f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
|
||||||
|
for bar in bars2:
|
||||||
|
height = bar.get_height()
|
||||||
|
if height < 0.01:
|
||||||
|
ax.annotate(f'{height:.6f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
else:
|
||||||
|
ax.annotate(f'{height:.4f}', xy=(bar.get_x() + bar.get_width()/2, height),
|
||||||
|
xytext=(0, 3), textcoords="offset points", ha='center', va='bottom', fontsize=9)
|
||||||
|
|
||||||
|
ax.set_ylabel('Время (сек)', fontsize=12)
|
||||||
|
ax.set_title('Время удаления 50 записей', fontsize=14, fontweight='bold')
|
||||||
|
ax.set_xticks(x)
|
||||||
|
ax.set_xticklabels(structures, fontsize=11)
|
||||||
|
ax.legend(fontsize=11)
|
||||||
|
ax.set_yscale('log')
|
||||||
|
ax.grid(True, alpha=0.3, axis='y')
|
||||||
|
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('docs/data/graph_delete.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user