You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.1 KiB
185 lines
4.1 KiB
#include "galgorithm.h"
|
|
#include "gheap.h"
|
|
#include "gpriority_queue.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdio.h> // for printf()
|
|
#include <stdlib.h> // for rand(), srand()
|
|
#include <time.h> // for clock()
|
|
|
|
typedef size_t T;
|
|
|
|
static int less(const void *const ctx, const void *const a, const void *const b)
|
|
{
|
|
(void)ctx;
|
|
return *((T *)a) < *((T *)b);
|
|
}
|
|
|
|
static void move(void *const dst, const void *const src)
|
|
{
|
|
*((T *)dst) = *((T *)src);
|
|
}
|
|
|
|
static double get_time(void)
|
|
{
|
|
return (double)clock() / CLOCKS_PER_SEC;
|
|
}
|
|
|
|
static void print_performance(const double t, const size_t m)
|
|
{
|
|
printf(": %.0lf Kops/s\n", m / t / 1000);
|
|
}
|
|
|
|
static void init_array(T *const a, const size_t n)
|
|
{
|
|
for (size_t i = 0; i < n; ++i) {
|
|
a[i] = rand();
|
|
}
|
|
}
|
|
|
|
static void perftest_heapsort(const struct gheap_ctx *const ctx,
|
|
T *const a, const size_t n, const size_t m)
|
|
{
|
|
printf("perftest_heapsort(n=%zu, m=%zu)", n, m);
|
|
|
|
double total_time = 0;
|
|
|
|
for (size_t i = 0; i < m / n; ++i) {
|
|
init_array(a, n);
|
|
|
|
const double start = get_time();
|
|
galgorithm_heapsort(ctx, a, n);
|
|
const double end = get_time();
|
|
|
|
total_time += end - start;
|
|
}
|
|
|
|
print_performance(total_time, m);
|
|
}
|
|
|
|
static void perftest_partial_sort(const struct gheap_ctx *const ctx,
|
|
T *const a, const size_t n, const size_t m)
|
|
{
|
|
const size_t k = n / 4;
|
|
|
|
printf("perftest_partial_sort(n=%zu, m=%zu, k=%zu)", n, m, k);
|
|
|
|
double total_time = 0;
|
|
|
|
for (size_t i = 0; i < m / n; ++i) {
|
|
init_array(a, n);
|
|
|
|
const double start = get_time();
|
|
galgorithm_partial_sort(ctx, a, n, k);
|
|
const double end = get_time();
|
|
|
|
total_time += end - start;
|
|
}
|
|
|
|
print_performance(total_time, m);
|
|
}
|
|
|
|
static void small_range_sorter(const void *const ctx, void *const a,
|
|
const size_t n)
|
|
{
|
|
galgorithm_heapsort(ctx, a, n);
|
|
}
|
|
|
|
static void perftest_nway_mergesort(const struct gheap_ctx *const ctx,
|
|
T *const a, const size_t n, const size_t m)
|
|
{
|
|
const size_t small_range_size = ((1 << 20) - 1) / 3;
|
|
const size_t subranges_count = 15;
|
|
|
|
printf("perftest_nway_mergesort(n=%zu, m=%zu, small_range_size=%zu, "
|
|
"subranges_count=%zu)", n, m, small_range_size, subranges_count);
|
|
|
|
double total_time = 0;
|
|
|
|
struct gheap_ctx small_range_sorter_ctx = *ctx;
|
|
small_range_sorter_ctx.fanout = 4;
|
|
|
|
for (size_t i = 0; i < m / n; ++i) {
|
|
init_array(a, n);
|
|
|
|
const double start = get_time();
|
|
T *const items_tmp_buf = malloc(sizeof(items_tmp_buf[0]) * n);
|
|
galgorithm_nway_mergesort(ctx, a, n,
|
|
&small_range_sorter, &small_range_sorter_ctx,
|
|
small_range_size, subranges_count, items_tmp_buf);
|
|
free(items_tmp_buf);
|
|
const double end = get_time();
|
|
|
|
total_time += end - start;
|
|
}
|
|
|
|
print_performance(total_time, m);
|
|
}
|
|
|
|
static void delete_item(void *item)
|
|
{
|
|
/* do nothing */
|
|
(void)item;
|
|
}
|
|
|
|
static void perftest_priority_queue(const struct gheap_ctx *const ctx,
|
|
T *const a, const size_t n, const size_t m)
|
|
{
|
|
printf("perftest_priority_queue(n=%zu, m=%zu)", n, m);
|
|
|
|
init_array(a, n);
|
|
struct gpriority_queue *const q = gpriority_queue_create_from_array(
|
|
ctx, &delete_item, a, n);
|
|
|
|
double start = get_time();
|
|
for (size_t i = 0; i < m; ++i) {
|
|
gpriority_queue_pop(q);
|
|
const T tmp = rand();
|
|
gpriority_queue_push(q, &tmp);
|
|
}
|
|
double end = get_time();
|
|
|
|
gpriority_queue_delete(q);
|
|
|
|
print_performance(end - start, m);
|
|
}
|
|
|
|
static void perftest(const struct gheap_ctx *const ctx, T *const a,
|
|
const size_t max_n)
|
|
{
|
|
size_t n = max_n;
|
|
while (n > 0) {
|
|
perftest_heapsort(ctx, a, n, max_n);
|
|
perftest_partial_sort(ctx, a, n, max_n);
|
|
perftest_nway_mergesort(ctx, a, n, max_n);
|
|
perftest_priority_queue(ctx, a, n, max_n);
|
|
|
|
n >>= 1;
|
|
}
|
|
}
|
|
|
|
static const struct gheap_ctx ctx_v = {
|
|
.fanout = 2,
|
|
.page_chunks = 1,
|
|
.item_size = sizeof(T),
|
|
.less_comparer = &less,
|
|
.less_comparer_ctx = NULL,
|
|
.item_mover = &move,
|
|
};
|
|
|
|
int main(void)
|
|
{
|
|
static const size_t MAX_N = 32 * 1024 * 1024;
|
|
|
|
printf("fanout=%zu, page_chunks=%zu, max_n=%zu\n",
|
|
ctx_v.fanout, ctx_v.page_chunks, MAX_N);
|
|
|
|
srand(0);
|
|
T *const a = malloc(sizeof(a[0]) * MAX_N);
|
|
|
|
perftest(&ctx_v, a, MAX_N);
|
|
|
|
free(a);
|
|
|
|
return 0;
|
|
}
|
|
|