diff --git a/benchmarks/hashset.c b/benchmarks/hashset.c deleted file mode 100644 index cf76176..0000000 --- a/benchmarks/hashset.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include "../src/macro_collections.h" - -int intcmp(int a, int b) -{ - return a - b; -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -COLLECTION_GENERATE(HASHSET, PUBLIC, set, hash_set, static, , int) - -int main(int argc, char const *argv[]) -{ - hash_set *set = set_new(50000, 0.9, intcmp, inthash); - //hash_set *set = set_new(intcmp); - - for (int i = -1000000; i <= 1000000; i++) - set_insert(set, i); - - hash_set_iter iter; - - size_t index; - int result, total_sum = 0; - for (set_iter_new(&iter, set); !set_iter_end(&iter);) - { - set_iter_next(&iter, &result, &index); - total_sum += result; - } - - set_free(set); - - return 0; -} diff --git a/benchmarks/io.c b/benchmarks/io.c new file mode 100644 index 0000000..d91913f --- /dev/null +++ b/benchmarks/io.c @@ -0,0 +1,144 @@ +/** + * io.c + * + * Creation Date: 12/04/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + * Input Output benchmarks. + */ +#include +#include +#include +#include +#include "macro_collections.h" +#include "timer.h" + +static int intcmp(int a, int b) +{ + return a - b; +} + +static size_t inthash(int t) +{ + size_t a = t; + a += ~(a << 15); + a ^= (a >> 10); + a += (a << 3); + a ^= (a >> 6); + a += ~(a << 11); + a ^= (a >> 16); + return a; +} + +double rrandom() +{ + return (double)rand() / ((double)RAND_MAX + 1.0); +} + +size_t randsize(size_t min, size_t max) +{ + return (size_t)floor(rrandom() * ((double)max - (double)min + 1.0) + (double)min); +} + +void shuffle(int *array) +{ + for (size_t i = 0; i < 10000000; i++) + { + size_t j = randsize(0, 10000000); + int tmp = array[j]; + array[j] = array[i]; + array[i] = tmp; + } +} + +COLLECTION_GENERATE(LIST, PUBLIC, l, list, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(STACK, PUBLIC, s, stack, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(QUEUE, PUBLIC, q, queue, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(DEQUE, PUBLIC, d, deque, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(LINKEDLIST, PUBLIC, ll, linked, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HEAP, PUBLIC, h, heap, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREESET, PUBLIC, ts, tset, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREEMAP, PUBLIC, tm, tmap, /* FMOD */, int, int) +COLLECTION_GENERATE(HASHSET, PUBLIC, hs, hset, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, int) + +#define ITERATION_BENCHMARK(NAME, PFX, sname, initfunc, insertbody, removebody) \ + void NAME##_iteration_benchmark(int *array) \ + { \ + timer_t timer; \ + int r; \ + \ + sname *collection = initfunc; \ + \ + TIMER_START(timer) \ + \ + for (int i = 0; i < 10000000; i++) \ + { \ + insertbody; \ + } \ + \ + TIMER_STOP(timer) \ + \ + TIMER_CALC(timer) \ + \ + size_t s1 = PFX##_count(collection); \ + \ + printf(" INPUT %10s TOOK %8.0lf milliseconds for %9lu elements\n", #NAME, timer.result, s1); \ + \ + for (int i = 0; i < 10000000; i++) \ + { \ + removebody; \ + } \ + \ + size_t s2 = PFX##_count(collection); \ + \ + printf("OUTPUT %10s TOOK %8.0lf milliseconds for %9lu elements\n", #NAME, timer.result, s1); \ + \ + PFX##_free(collection); \ + \ + assert(s2 == 0); \ + } + +ITERATION_BENCHMARK(DEQUE, d, deque, d_new(10000000), d_push_back(collection, array[i]), d_pop_back(collection)) +ITERATION_BENCHMARK(HASHMAP, hm, hmap, hm_new(10000000, 0.8, intcmp, inthash), hm_insert(collection, array[i], array[i]), hm_remove(collection, array[i], &r)) +ITERATION_BENCHMARK(HASHSET, hs, hset, hs_new(10000000, 0.8, intcmp, inthash), hs_insert(collection, array[i]), hs_remove(collection, array[i])) +ITERATION_BENCHMARK(HEAP, h, heap, h_new(10000000, MaxHeap, intcmp), h_insert(collection, array[i]), h_remove(collection, &r)) +ITERATION_BENCHMARK(LINKEDLIST, ll, linked, ll_new(), ll_push_back(collection, i), ll_pop_back(collection)) +ITERATION_BENCHMARK(LIST, l, list, l_new(10000000), l_push_back(collection, i), l_pop_back(collection)) +ITERATION_BENCHMARK(QUEUE, q, queue, q_new(10000000), q_enqueue(collection, i), q_dequeue(collection)) +ITERATION_BENCHMARK(STACK, s, stack, s_new(10000000), s_push(collection, i), s_pop(collection)) +ITERATION_BENCHMARK(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(collection, array[i], array[i]), tm_remove(collection, array[i], &r)) +ITERATION_BENCHMARK(TREESET, ts, tset, ts_new(intcmp), ts_insert(collection, array[i]), ts_remove(collection, array[i])) + +int main(int argc, char const *argv[]) +{ + int *array = malloc(10000000 * sizeof(int)); + + if (!array) + { + printf("Allocation failed\n"); + return 1; + } + + for (int i = -5000000; i < 5000000; i++) + array[i + 5000000] = i; + + shuffle(array); + + DEQUE_iteration_benchmark(array); + HASHMAP_iteration_benchmark(array); + HASHSET_iteration_benchmark(array); + HEAP_iteration_benchmark(array); + LINKEDLIST_iteration_benchmark(array); + LIST_iteration_benchmark(array); + QUEUE_iteration_benchmark(array); + STACK_iteration_benchmark(array); + TREEMAP_iteration_benchmark(array); + TREESET_iteration_benchmark(array); + + free(array); + + return 0; +} diff --git a/benchmarks/iteration.c b/benchmarks/iteration.c new file mode 100644 index 0000000..c0656d5 --- /dev/null +++ b/benchmarks/iteration.c @@ -0,0 +1,107 @@ +/** + * iteration.c + * + * Creation Date: 12/04/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + * Iteration benchmarks. + */ +#include +#include +#include +#include "macro_collections.h" +#include "timer.h" + +static int intcmp(int a, int b) +{ + return a - b; +} + +static size_t inthash(int t) +{ + size_t a = t; + a += ~(a << 15); + a ^= (a >> 10); + a += (a << 3); + a ^= (a >> 6); + a += ~(a << 11); + a ^= (a >> 16); + return a; +} + +COLLECTION_GENERATE(LIST, PUBLIC, l, list, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(STACK, PUBLIC, s, stack, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(QUEUE, PUBLIC, q, queue, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(DEQUE, PUBLIC, d, deque, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(LINKEDLIST, PUBLIC, ll, linked, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HEAP, PUBLIC, h, heap, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREESET, PUBLIC, ts, tset, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(TREEMAP, PUBLIC, tm, tmap, /* FMOD */, int, int) +COLLECTION_GENERATE(HASHSET, PUBLIC, hs, hset, /* FMOD */, /* K */, int) +COLLECTION_GENERATE(HASHMAP, PUBLIC, hm, hmap, /* FMOD */, int, int) + +#define ITERATION_BENCHMARK(NAME, PFX, sname, initfunc, insertbody, iternext) \ + void NAME##_iteration_benchmark(void) \ + { \ + timer_t timer; \ + \ + sname *collection = initfunc; \ + \ + for (int i = -5000000; i < 5000000; i++) \ + { \ + insertbody; \ + } \ + \ + sname##_iter iter; \ + \ + size_t i; \ + int k, v; \ + int64_t sum = 0; \ + \ + TIMER_START(timer) \ + \ + for (PFX##_iter_new(&iter, collection); !PFX##_iter_end(&iter);) \ + { \ + iternext; \ + sum += k; \ + } \ + \ + TIMER_STOP(timer) \ + \ + TIMER_CALC(timer) \ + \ + printf("ITERATION %10s TOOK %.2lf milliseconds over %9lu elements\n", #NAME, timer.result, PFX##_count(collection)); \ + \ + PFX##_free(collection); \ + \ + assert(sum == -5000000); \ + } + +ITERATION_BENCHMARK(DEQUE, d, deque, d_new(10000000), d_push_back(collection, i), d_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(HASHMAP, hm, hmap, hm_new(10000000, 0.8, intcmp, inthash), hm_insert(collection, i, i), hm_iter_next(&iter, &k, &v, &i)) +ITERATION_BENCHMARK(HASHSET, hs, hset, hs_new(10000000, 0.8, intcmp, inthash), hs_insert(collection, i), hs_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(HEAP, h, heap, h_new(10000000, MaxHeap, intcmp), h_insert(collection, i), h_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(LINKEDLIST, ll, linked, ll_new(), ll_push_back(collection, i), ll_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(LIST, l, list, l_new(10000000), l_push_back(collection, i), l_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(QUEUE, q, queue, q_new(10000000), q_enqueue(collection, i), q_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(STACK, s, stack, s_new(10000000), s_push(collection, i), s_iter_next(&iter, &k, &i)) +ITERATION_BENCHMARK(TREEMAP, tm, tmap, tm_new(intcmp), tm_insert(collection, i, i), tm_iter_next(&iter, &k, &v, &i)) +ITERATION_BENCHMARK(TREESET, ts, tset, ts_new(intcmp), ts_insert(collection, i), ts_iter_next(&iter, &k, &i)) + +int main(int argc, char const *argv[]) +{ + DEQUE_iteration_benchmark(); + HASHMAP_iteration_benchmark(); + HASHSET_iteration_benchmark(); + HEAP_iteration_benchmark(); + LINKEDLIST_iteration_benchmark(); + LIST_iteration_benchmark(); + QUEUE_iteration_benchmark(); + STACK_iteration_benchmark(); + TREEMAP_iteration_benchmark(); + TREESET_iteration_benchmark(); + + return 0; +} diff --git a/benchmarks/timer.h b/benchmarks/timer.h new file mode 100644 index 0000000..07858c6 --- /dev/null +++ b/benchmarks/timer.h @@ -0,0 +1,27 @@ +/** + * timer.h + * + * Creation Date: 12/04/2019 + * + * Authors: + * Leonardo Vencovsky (https://github.com/LeoVen) + * + * Simple timer macros. + */ +#include + +typedef struct timer_s +{ + clock_t start; + clock_t stop; + double result; +} timer_t; + +#define TIMER_START(timer) \ + timer.start = clock(); + +#define TIMER_STOP(timer) \ + timer.stop = clock(); + +#define TIMER_CALC(timer) \ + timer.result = (double)(((timer.stop - timer.start) * 1000.0) / CLOCKS_PER_SEC); diff --git a/benchmarks/treeset.c b/benchmarks/treeset.c deleted file mode 100644 index 9f5d5e0..0000000 --- a/benchmarks/treeset.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include "../src/macro_collections.h" - -int intcmp(int a, int b) -{ - return a - b; -} - -size_t inthash(int t) -{ - size_t a = t; - a += ~(a << 15); - a ^= (a >> 10); - a += (a << 3); - a ^= (a >> 6); - a += ~(a << 11); - a ^= (a >> 16); - return a; -} - -COLLECTION_GENERATE(TREESET, PUBLIC, set, hash_set, static, , int) - -int main(int argc, char const *argv[]) -{ - //hash_set *set = set_new(50000, 0.9, intcmp, inthash); - hash_set *set = set_new(intcmp); - - for (int i = -1000000; i <= 1000000; i++) - set_insert(set, i); - - hash_set_iter iter; - - size_t index; - int result, total_sum = 0; - for (set_iter_new(&iter, set); !set_iter_end(&iter);) - { - set_iter_next(&iter, &result, &index); - total_sum += result; - } - - set_free(set); - - return 0; -} diff --git a/tests/foreach.c b/tests/foreach.c index da59bf9..6543687 100644 --- a/tests/foreach.c +++ b/tests/foreach.c @@ -113,26 +113,26 @@ int main(void) }) printf("\n-------------------- FOR_EACH --------------------\n"); - if (sum0 == 50005000) - printf("%10s PASSED\n", "LIST"); - if (sum1 == 50005000) - printf("%10s PASSED\n", "STACK"); - if (sum2 == 50005000) - printf("%10s PASSED\n", "QUEUE"); if (sum3 == 50005000) printf("%10s PASSED\n", "DEQUE"); - if (sum4 == 50005000) - printf("%10s PASSED\n", "LINKEDLIST"); - if (sum5 == 50005000) - printf("%10s PASSED\n", "HEAP"); - if (sum6 == 50005000) - printf("%10s PASSED\n", "TREESET"); - if (sum7 == 50005000 && sum8 == 50005000) - printf("%10s PASSED\n", "TREEMAP"); if (sum9 == 50005000) printf("%10s PASSED\n", "HASHSET"); if (sum10 == 50005000 && sum11 == 50005000) printf("%10s PASSED\n", "HASHMAP"); + if (sum5 == 50005000) + printf("%10s PASSED\n", "HEAP"); + if (sum4 == 50005000) + printf("%10s PASSED\n", "LINKEDLIST"); + if (sum0 == 50005000) + printf("%10s PASSED\n", "LIST"); + if (sum2 == 50005000) + printf("%10s PASSED\n", "QUEUE"); + if (sum1 == 50005000) + printf("%10s PASSED\n", "STACK"); + if (sum7 == 50005000 && sum8 == 50005000) + printf("%10s PASSED\n", "TREEMAP"); + if (sum6 == 50005000) + printf("%10s PASSED\n", "TREESET"); printf("\n\n"); @@ -182,26 +182,26 @@ int main(void) }) printf("-------------------- FOR_EACH_REV --------------------\n"); - if (sum0 == 50005000) - printf("%10s PASSED\n", "LIST"); - if (sum1 == 50005000) - printf("%10s PASSED\n", "STACK"); - if (sum2 == 50005000) - printf("%10s PASSED\n", "QUEUE"); if (sum3 == 50005000) printf("%10s PASSED\n", "DEQUE"); - if (sum4 == 50005000) - printf("%10s PASSED\n", "LINKEDLIST"); - if (sum5 == 50005000) - printf("%10s PASSED\n", "HEAP"); - if (sum6 == 50005000) - printf("%10s PASSED\n", "TREESET"); - if (sum7 == 50005000 && sum8 == 50005000) - printf("%10s PASSED\n", "TREEMAP"); if (sum9 == 50005000) printf("%10s PASSED\n", "HASHSET"); if (sum10 == 50005000 && sum11 == 50005000) printf("%10s PASSED\n", "HASHMAP"); + if (sum5 == 50005000) + printf("%10s PASSED\n", "HEAP"); + if (sum4 == 50005000) + printf("%10s PASSED\n", "LINKEDLIST"); + if (sum0 == 50005000) + printf("%10s PASSED\n", "LIST"); + if (sum2 == 50005000) + printf("%10s PASSED\n", "QUEUE"); + if (sum1 == 50005000) + printf("%10s PASSED\n", "STACK"); + if (sum7 == 50005000 && sum8 == 50005000) + printf("%10s PASSED\n", "TREEMAP"); + if (sum6 == 50005000) + printf("%10s PASSED\n", "TREESET"); l_free(l); ll_free(ll);