Finished benchmark and plotting

This commit is contained in:
2025-05-05 01:34:33 +02:00
parent b14156589c
commit e45091b066
7 changed files with 183 additions and 23 deletions
+3 -2
View File
@@ -1,2 +1,3 @@
/dist benchmark
benchmarks results.csv
charts/
+66 -14
View File
@@ -1,39 +1,43 @@
#include "bst/bst.h" #include "bst/bst.h"
#include "list/list.h" #include "list/list.h"
#include <cstdio>
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <random> #include <random>
#include <chrono> #include <chrono>
void measureBST(std::set<int> *sequence){ void measureList(std::set<int> *sequence, FILE *file){
int buildTime = 0, searchTime = 0, deleteTime = 0; float buildTime = 0, searchTime = 0, deleteTime = 0;
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
std::cout << "- Running test " << i + 1 << "/10\r"; std::cout << "- Running list " << i + 1 << "/10\r";
fflush(stdout); fflush(stdout);
// Measure build time // Measure build time
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
Tree *root = nullptr; List *head = nullptr;
for (int value : *sequence) { for (int value : *sequence) {
root = insert(root, value); head = insert(head, value);
} }
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start; std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Now we run the search // Now we run the search
start = std::chrono::high_resolution_clock::now();
for (int value : *sequence) { for (int value : *sequence) {
search(root, value); search(head, value);
} }
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start; elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Measure deletion time for tree // Measure deletion time for list
start = std::chrono::high_resolution_clock::now(); start = std::chrono::high_resolution_clock::now();
freeTree(root); while(head != nullptr){
head = remove(head);
}
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start; elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
@@ -43,9 +47,51 @@ void measureBST(std::set<int> *sequence){
searchTime /= 10; searchTime /= 10;
deleteTime /= 10; deleteTime /= 10;
std::cout << "- Tree built in " << buildTime << "ms" << std::endl; std::cout << "- List built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl;
std::cout << "- Tree searched in " << searchTime << "ms" << std::endl; fprintf(file, "List,%f,%f,%f\n", buildTime, searchTime, deleteTime);
std::cout << "- Tree deleted in " << deleteTime << "ms" << std::endl; }
void measureBST(std::set<int> *sequence, FILE *file){
float buildTime = 0, searchTime = 0, deleteTime = 0;
for (int i = 0; i < 10; i++) {
std::cout << "- Running bst " << i + 1 << "/10\r";
fflush(stdout);
// Measure build time
auto start = std::chrono::high_resolution_clock::now();
Tree *root = nullptr;
for (int value : *sequence) {
root = insert(root, value);
}
root = balance(root);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
buildTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Now we run the search
start = std::chrono::high_resolution_clock::now();
for (int value : *sequence) {
search(root, value);
}
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
searchTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
// Measure deletion time for tree
start = std::chrono::high_resolution_clock::now();
deleteTree(root);
end = std::chrono::high_resolution_clock::now();
elapsed_seconds = end - start;
deleteTime += elapsed_seconds.count() * 1000; // Convert to milliseconds
}
buildTime /= 10;
searchTime /= 10;
deleteTime /= 10;
std::cout << "- Tree built in " << buildTime << "ms | searched in " << searchTime << "ms | deleted in " << deleteTime << "ms" << std::endl;
fprintf(file, "BST,%f,%f,%f\n", buildTime, searchTime, deleteTime);
} }
int main() { int main() {
@@ -54,19 +100,25 @@ int main() {
std::mt19937 gen(rd()); std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 1000000); std::uniform_int_distribution<> dis(1, 1000000);
for (int n = 1; n < 16; n++) { // Open a file for writing results
FILE *file = fopen("results.csv", "w");
fprintf(file, "Elements,Structure,BuildTime,SearchTime,DeleteTime\n");
for (int n = 1; n < 26; n++) {
std::set<int> sequence; std::set<int> sequence;
while (sequence.size() < n * 1000) { while (sequence.size() < n * 1000) {
sequence.insert(dis(gen)); sequence.insert(dis(gen));
} }
// Display this like a cascade // Display this like a cascade
std::cout << "Running tests for " << n * 1000 << " elements..." std::cout << "Running tests for " << n * 1000 << " elements..."
<< std::endl; << std::endl;
measureBST(&sequence); measureList(&sequence, file);
measureBST(&sequence, file);
} }
fclose(file);
return 0; return 0;
} }
+30 -3
View File
@@ -24,10 +24,37 @@ Tree *search(Tree *root, int value) {
return nullptr; return nullptr;
} }
void freeTree(Tree *root) { void traverseInOrder(Tree *root, std::vector<int> *vec) {
if (root != nullptr) { if (root != nullptr) {
freeTree(root->left); traverseInOrder(root->left, vec);
freeTree(root->right); vec->push_back(root->info);
traverseInOrder(root->right, vec);
}
}
Tree *rebuild(std::vector<int> *vec, int start, int end) {
if (start > end)
return nullptr;
int mid = (start + end) / 2;
Tree *node = new Tree();
node->info = vec->at(mid);
node->left = rebuild(vec, start, mid - 1);
node->right = rebuild(vec, mid + 1, end);
return node;
}
Tree *balance(Tree *root) {
std::vector<int> vec;
traverseInOrder(root, &vec);
return rebuild(&vec, 0, vec.size() - 1);
}
void deleteTree(Tree *root) {
if (root != nullptr) {
deleteTree(root->left);
deleteTree(root->right);
delete root; delete root;
} }
} }
+6 -1
View File
@@ -1,3 +1,5 @@
#include <vector>
struct Tree { struct Tree {
int info; int info;
Tree *left; Tree *left;
@@ -6,4 +8,7 @@ struct Tree {
Tree *insert(Tree *root, int value); Tree *insert(Tree *root, int value);
Tree *search(Tree *root, int value); Tree *search(Tree *root, int value);
void freeTree(Tree *root); void traverseInOrder(Tree *root,std::vector<int> &vec);
Tree *rebuild(std::vector<int> *vec, int start, int end);
Tree *balance(Tree *root);
void deleteTree(Tree *root);
+33 -7
View File
@@ -1,25 +1,26 @@
#include "list.h" #include "list.h"
#include <sys/types.h>
List *insert(List *head, int data) { List *insert(List *head, int value) {
if (head == nullptr) { if (head == nullptr) {
List *node = new List(); List *node = new List();
node->data = data; node->data = value;
node->next = nullptr; node->next = nullptr;
return node; return node;
} }
if (head->data > data) { if (head->data > value) {
List *newHead = new List(); List *newHead = new List();
newHead->data = data; newHead->data = value;
newHead->next = head; newHead->next = head;
head = newHead; head = newHead;
} else { } else {
List *tmp = head; List *tmp = head;
while (tmp->next != nullptr && tmp->data < data) { while (tmp->next != nullptr && tmp->data < value) {
tmp = head->next; tmp = tmp->next;
} }
List *tail = new List(); List *tail = new List();
tail->data = data; tail->data = value;
// Set the pointer to the next, we don't know if its at the end or not // Set the pointer to the next, we don't know if its at the end or not
tail->next = tmp->next; tail->next = tmp->next;
tmp->next = tail; tmp->next = tail;
@@ -27,3 +28,28 @@ List *insert(List *head, int data) {
return head; return head;
} }
List *search(List *list, int value) {
List *ptr = list;
while (ptr != nullptr && ptr->data != value) {
ptr = ptr->next;
}
if (ptr->data == value) {
return ptr;
}
return nullptr;
}
// Remove the first element
List *remove(List *head) {
if (head == nullptr) {
return nullptr;
}
List *newHead = head->next;
delete head;
return newHead;
}
+2
View File
@@ -4,3 +4,5 @@ struct List {
}; };
List *insert(List *head, int data); List *insert(List *head, int data);
List *search(List *list, int value);
List* remove(List *head);
+47
View File
@@ -0,0 +1,47 @@
import matplotlib.pyplot as plt
def plot(header:str, first:list[int], second:list[int], log=False):
plt.figure(figsize=(10, 6))
plt.plot(range(1000,25001,1000), first, label="Lista")
plt.plot(range(1000,25001,1000), second, label="Drzewo BST")
plt.xlabel("Rozmiar tablicy")
plt.ylabel("Czas (ms)")
if log:
plt.yscale('log', base=2)
plt.title(header)
plt.legend()
plt.savefig(f"./charts/{header}.png")
if __name__ == "__main__":
with open('results.csv', 'r') as file:
data = file.read()
lines = data.split('\n')
headers = lines[0].split(',')
values = [line.split(',') for line in lines[1:]]
bstTimes = {
"build":[],
"search":[],
"delete":[]
}
listTimes = {
"build":[],
"search":[],
"delete":[]
}
for row in values:
if row[0] == 'BST':
bstTimes['build'].append(float(row[1]))
bstTimes['search'].append(float(row[2]))
bstTimes['delete'].append(float(row[3]))
elif row[0] == 'List':
listTimes['build'].append(float(row[1]))
listTimes['search'].append(float(row[2]))
listTimes['delete'].append(float(row[3]))
plot("Tworzenie", listTimes['build'], bstTimes['build'])
plot("Wyszukiwanie", listTimes['search'], bstTimes['search'], log=True)
plot("Usuwanie", listTimes['delete'], bstTimes['delete'])