summaryrefslogtreecommitdiffstats
path: root/benchmark
diff options
context:
space:
mode:
Diffstat (limited to 'benchmark')
-rw-r--r--benchmark/.clang-tidy3
-rw-r--r--benchmark/bench.h16
-rw-r--r--benchmark/dict_bench.c16
-rw-r--r--benchmark/meson.build11
-rw-r--r--benchmark/tree_bench.c77
5 files changed, 63 insertions, 60 deletions
diff --git a/benchmark/.clang-tidy b/benchmark/.clang-tidy
index b89626f..6b582c0 100644
--- a/benchmark/.clang-tidy
+++ b/benchmark/.clang-tidy
@@ -1,4 +1,4 @@
-# Copyright 2020-2022 David Robillard <d@drobilla.net>
+# Copyright 2020-2025 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
Checks: >
@@ -6,6 +6,7 @@ Checks: >
-android-cloexec-fopen,
-bugprone-easily-swappable-parameters,
-cert-err33-c,
+ -clang-analyzer-core.NonNullParamChecker,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-llvm-header-guard,
-performance-no-int-to-ptr,
diff --git a/benchmark/bench.h b/benchmark/bench.h
index bcfe077..2a25b11 100644
--- a/benchmark/bench.h
+++ b/benchmark/bench.h
@@ -1,33 +1,29 @@
-// Copyright 2011-2020 David Robillard <d@drobilla.net>
+// Copyright 2011-2024 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
#ifndef BENCH_H
#define BENCH_H
-#include <time.h>
+#include <glib.h>
-typedef struct timespec BenchmarkTime;
+typedef gint64 BenchmarkTime;
static inline double
bench_elapsed_s(const BenchmarkTime* start, const BenchmarkTime* end)
{
- return ((double)(end->tv_sec - start->tv_sec) +
- ((double)(end->tv_nsec - start->tv_nsec) * 0.000000001));
+ return (double)(*end - *start) * 0.000001;
}
static inline BenchmarkTime
bench_start(void)
{
- BenchmarkTime start_t;
- clock_gettime(CLOCK_REALTIME, &start_t);
- return start_t;
+ return g_get_monotonic_time();
}
static inline double
bench_end(const BenchmarkTime* start_t)
{
- BenchmarkTime end_t;
- clock_gettime(CLOCK_REALTIME, &end_t);
+ const BenchmarkTime end_t = g_get_monotonic_time();
return bench_elapsed_s(start_t, &end_t);
}
diff --git a/benchmark/dict_bench.c b/benchmark/dict_bench.c
index 5d9acd0..9184fb4 100644
--- a/benchmark/dict_bench.c
+++ b/benchmark/dict_bench.c
@@ -12,10 +12,10 @@ typedef struct {
#define ZIX_HASH_KEY_TYPE ZixChunk
#define ZIX_HASH_RECORD_TYPE ZixChunk
-#include "zix/attributes.h"
-#include "zix/digest.h"
-#include "zix/hash.h"
-#include "zix/status.h"
+#include <zix/attributes.h>
+#include <zix/digest.h>
+#include <zix/hash.h>
+#include <zix/status.h>
ZIX_DISABLE_GLIB_WARNINGS
#include <glib.h>
@@ -27,7 +27,6 @@ ZIX_RESTORE_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
typedef struct {
ZixChunk* chunks;
@@ -92,6 +91,7 @@ read_inputs(FILE* const fd)
inputs.chunks = new_chunks;
inputs.chunks[inputs.n_chunks].buf = (char*)malloc(buf_len);
inputs.chunks[inputs.n_chunks].len = this_str_len;
+ assert(inputs.chunks[inputs.n_chunks].buf);
memcpy(inputs.chunks[inputs.n_chunks].buf, inputs.buf, buf_len);
this_str_len = 0;
if (++inputs.n_chunks == max_n_strings) {
@@ -128,6 +128,8 @@ run(FILE* const fd)
FILE* insert_dat = fopen("dict_insert.txt", "w");
FILE* search_dat = fopen("dict_search.txt", "w");
+ assert(insert_dat);
+ assert(search_dat);
fprintf(insert_dat, "# n\tGHashTable\tZixHash\n");
fprintf(search_dat, "# n\tGHashTable\tZixHash\n");
@@ -146,7 +148,7 @@ run(FILE* const fd)
// Benchmark insertion
// GHashTable
- struct timespec insert_start = bench_start();
+ BenchmarkTime insert_start = bench_start();
for (size_t i = 0; i < n; ++i) {
g_hash_table_insert(hash, inputs.chunks[i].buf, inputs.chunks[i].buf);
}
@@ -164,7 +166,7 @@ run(FILE* const fd)
// Benchmark search
// GHashTable
- struct timespec search_start = bench_start();
+ BenchmarkTime search_start = bench_start();
for (size_t i = 0; i < n; ++i) {
const size_t index = (size_t)(lcg64(seed + i) % n);
char* volatile match =
diff --git a/benchmark/meson.build b/benchmark/meson.build
index d3b04ea..54cac3d 100644
--- a/benchmark/meson.build
+++ b/benchmark/meson.build
@@ -15,15 +15,19 @@ glib_dep = dependency(
if glib_dep.found()
build_benchmarks = true
- benchmark_c_args = platform_c_args
+ benchmark_c_args = extra_c_args
+ benchmark_c_suppressions = []
if cc.get_id() in ['clang', 'emscripten']
benchmark_c_suppressions = [
+ '-Wno-bad-function-cast',
+ '-Wno-c11-extensions', # Glib
'-Wno-reserved-identifier',
]
-
- benchmark_c_args += cc.get_supported_arguments(benchmark_c_suppressions)
+ elif cc.get_id() == 'gcc'
+ benchmark_c_suppressions = ['-Wno-bad-function-cast']
endif
+ benchmark_c_args += cc.get_supported_arguments(benchmark_c_suppressions)
foreach benchmark : benchmarks
benchmark(
@@ -33,6 +37,7 @@ if glib_dep.found()
files('@0@.c'.format(benchmark)),
c_args: c_suppressions + benchmark_c_args,
dependencies: [zix_dep, glib_dep],
+ implicit_include_directories: false,
include_directories: include_dirs,
),
)
diff --git a/benchmark/tree_bench.c b/benchmark/tree_bench.c
index b9e230e..849216b 100644
--- a/benchmark/tree_bench.c
+++ b/benchmark/tree_bench.c
@@ -1,26 +1,24 @@
// Copyright 2011-2020 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
+#include "../test/test_data.h"
#include "bench.h"
#include "warnings.h"
-#include "../test/test_data.h"
-
-#include "zix/attributes.h"
-#include "zix/btree.h"
-#include "zix/status.h"
-#include "zix/tree.h"
+#include <zix/attributes.h>
+#include <zix/btree.h>
+#include <zix/status.h>
+#include <zix/tree.h>
ZIX_DISABLE_GLIB_WARNINGS
#include <glib.h>
ZIX_RESTORE_WARNINGS
+#include <assert.h>
#include <inttypes.h>
-#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include <time.h>
#ifndef MIN
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
@@ -55,15 +53,11 @@ g_int_cmp(const void* a, const void* b, void* user_data)
return int_cmp(a, b, user_data);
}
-ZIX_LOG_FUNC(1, 2)
static int
-test_fail(const char* fmt, ...)
+test_fail(const char* const prefix, const uintptr_t value)
{
- va_list args;
- va_start(args, fmt);
fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, args);
- va_end(args);
+ fprintf(stderr, "%s %" PRIuPTR "\n", prefix, value);
return EXIT_FAILURE;
}
@@ -87,32 +81,32 @@ bench_zix_tree(size_t n_elems,
ZixTree* t = zix_tree_new(NULL, false, int_cmp, NULL, NULL, NULL);
// Insert n_elems elements
- struct timespec insert_start = bench_start();
+ BenchmarkTime insert_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
ZixStatus status = zix_tree_insert(t, (void*)r, &ti);
if (status) {
- return test_fail("Failed to insert %" PRIuPTR "\n", r);
+ return test_fail("Failed to insert", r);
}
}
fprintf(insert_dat, "\t%lf", bench_end(&insert_start));
// Search for all elements
- struct timespec search_start = bench_start();
+ BenchmarkTime search_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
if (zix_tree_find(t, (void*)r, &ti)) {
- return test_fail("Failed to find %" PRIuPTR "\n", r);
+ return test_fail("Failed to find", r);
}
if ((uintptr_t)zix_tree_get(ti) != r) {
- return test_fail("Failed to get %" PRIuPTR "\n", r);
+ return test_fail("Failed to get", r);
}
}
fprintf(search_dat, "\t%lf", bench_end(&search_start));
// Iterate over all elements
- struct timespec iter_start = bench_start();
+ BenchmarkTime iter_start = bench_start();
for (ZixTreeIter* iter = zix_tree_begin(t); !zix_tree_iter_is_end(iter);
iter = zix_tree_iter_next(iter)) {
volatile void* const value = zix_tree_get(iter);
@@ -121,16 +115,16 @@ bench_zix_tree(size_t n_elems,
fprintf(iter_dat, "\t%lf", bench_end(&iter_start));
// Delete all elements
- struct timespec del_start = bench_start();
+ BenchmarkTime del_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
ZixTreeIter* item = NULL;
if (zix_tree_find(t, (void*)r, &item)) {
- return test_fail("Failed to find %" PRIuPTR " to delete\n", r);
+ return test_fail("Failed on delete to find", r);
}
if (zix_tree_remove(t, item)) {
- return test_fail("Failed to remove %" PRIuPTR "\n", r);
+ return test_fail("Failed to remove", r);
}
}
fprintf(del_dat, "\t%lf", bench_end(&del_start));
@@ -154,33 +148,33 @@ bench_zix_btree(size_t n_elems,
ZixBTree* t = zix_btree_new(NULL, int_cmp, NULL);
// Insert n_elems elements
- struct timespec insert_start = bench_start();
+ BenchmarkTime insert_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
ZixStatus status = zix_btree_insert(t, (void*)r);
if (status) {
- return test_fail("Failed to insert %" PRIuPTR "\n", r);
+ return test_fail("Failed to insert", r);
}
}
fprintf(insert_dat, "\t%lf", bench_end(&insert_start));
// Search for all elements
- struct timespec search_start = bench_start();
+ BenchmarkTime search_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
if (zix_btree_find(t, (void*)r, &ti)) {
- return test_fail("Failed to find %" PRIuPTR "\n", r);
+ return test_fail("Failed to find", r);
}
if ((uintptr_t)zix_btree_get(ti) != r) {
- return test_fail("Failed to get %" PRIuPTR "\n", r);
+ return test_fail("Failed to get", r);
}
}
fprintf(search_dat, "\t%lf", bench_end(&search_start));
// Iterate over all elements
- struct timespec iter_start = bench_start();
- ZixBTreeIter iter = zix_btree_begin(t);
+ BenchmarkTime iter_start = bench_start();
+ ZixBTreeIter iter = zix_btree_begin(t);
for (; !zix_btree_iter_is_end(iter); zix_btree_iter_increment(&iter)) {
volatile void* const value = zix_btree_get(iter);
(void)value;
@@ -188,14 +182,14 @@ bench_zix_btree(size_t n_elems,
fprintf(iter_dat, "\t%lf", bench_end(&iter_start));
// Delete all elements
- struct timespec del_start = bench_start();
+ BenchmarkTime del_start = bench_start();
for (size_t i = 0; i < n_elems; i++) {
r = unique_rand(i);
void* removed = NULL;
ZixBTreeIter next = zix_btree_end(t);
if (zix_btree_remove(t, (void*)r, &removed, &next)) {
- return test_fail("Failed to remove %" PRIuPTR "\n", r);
+ return test_fail("Failed to remove", r);
}
}
fprintf(del_dat, "\t%lf", bench_end(&del_start));
@@ -218,31 +212,31 @@ bench_glib(size_t n_elems,
GSequence* t = g_sequence_new(NULL);
// Insert n_elems elements
- struct timespec insert_start = bench_start();
+ BenchmarkTime insert_start = bench_start();
for (size_t i = 0; i < n_elems; ++i) {
r = unique_rand(i);
GSequenceIter* iter =
g_sequence_insert_sorted(t, (void*)r, g_int_cmp, NULL);
if (!iter || g_sequence_iter_is_end(iter)) {
- return test_fail("Failed to insert %" PRIuPTR "\n", r);
+ return test_fail("Failed to insert", r);
}
}
fprintf(insert_dat, "\t%lf", bench_end(&insert_start));
// Search for all elements
- struct timespec search_start = bench_start();
+ BenchmarkTime search_start = bench_start();
for (size_t i = 0; i < n_elems; ++i) {
r = unique_rand(i);
GSequenceIter* iter = g_sequence_lookup(t, (void*)r, g_int_cmp, NULL);
if (!iter || g_sequence_iter_is_end(iter)) {
- return test_fail("Failed to find %" PRIuPTR "\n", r);
+ return test_fail("Failed to find", r);
}
}
fprintf(search_dat, "\t%lf", bench_end(&search_start));
// Iterate over all elements
- struct timespec iter_start = bench_start();
+ BenchmarkTime iter_start = bench_start();
for (GSequenceIter* iter = g_sequence_get_begin_iter(t);
!g_sequence_iter_is_end(iter);
iter = g_sequence_iter_next(iter)) {
@@ -251,12 +245,12 @@ bench_glib(size_t n_elems,
fprintf(iter_dat, "\t%lf", bench_end(&iter_start));
// Delete all elements
- struct timespec del_start = bench_start();
+ BenchmarkTime del_start = bench_start();
for (size_t i = 0; i < n_elems; ++i) {
r = unique_rand(i);
GSequenceIter* iter = g_sequence_lookup(t, (void*)r, g_int_cmp, NULL);
if (!iter || g_sequence_iter_is_end(iter)) {
- return test_fail("Failed to remove %" PRIuPTR "\n", r);
+ return test_fail("Failed to remove", r);
}
g_sequence_remove(iter);
}
@@ -286,6 +280,11 @@ main(int argc, char** argv)
FILE* search_dat = fopen("tree_search.txt", "w");
FILE* iter_dat = fopen("tree_iterate.txt", "w");
FILE* del_dat = fopen("tree_delete.txt", "w");
+ assert(insert_dat);
+ assert(search_dat);
+ assert(iter_dat);
+ assert(del_dat);
+
fprintf(insert_dat, HEADER);
fprintf(search_dat, HEADER);
fprintf(iter_dat, HEADER);