aboutsummaryrefslogtreecommitdiff
path: root/tests/bench/trees.c
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tests/bench/trees.c
a
Diffstat (limited to 'tests/bench/trees.c')
-rw-r--r--tests/bench/trees.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/tests/bench/trees.c b/tests/bench/trees.c
new file mode 100644
index 0000000..df46447
--- /dev/null
+++ b/tests/bench/trees.c
@@ -0,0 +1,85 @@
+/* a full binary tree of depth D. checksum is the node count, 8191.
+ malloc: one malloc per node, then a recursive free. same shape as new().
+ arena: one buffer, a bump pointer, no allocator inside the loop.
+ usage: trees malloc|arena REPS */
+#include <stdio.h>
+#include <stdlib.h>
+
+enum { D = 12, EXPECT = 8191 };
+
+typedef struct node {
+ struct node *left, *right;
+} node;
+
+static node *make(int d)
+{
+ node *n = (node *)malloc(sizeof *n);
+ if (d > 0) {
+ n->left = make(d - 1);
+ n->right = make(d - 1);
+ } else
+ n->left = n->right = 0;
+ return n;
+}
+
+static int check(const node *n)
+{
+ if (!n->left) return 1;
+ return 1 + check(n->left) + check(n->right);
+}
+
+static void destroy(node *n)
+{
+ if (!n) return;
+ destroy(n->left);
+ destroy(n->right);
+ free(n);
+}
+
+static node *bump;
+
+static node *make_at(int d)
+{
+ node *n = bump++;
+ if (d > 0) {
+ n->left = make_at(d - 1);
+ n->right = make_at(d - 1);
+ } else
+ n->left = n->right = 0;
+ return n;
+}
+
+int main(int argc, char **argv)
+{
+ int reps, r = 0, k, arena, nodes;
+ node *buf = 0;
+ if (argc != 3) return 2;
+ arena = argv[1][0] == 'a';
+ reps = atoi(argv[2]);
+ nodes = (1 << (D + 1)) - 1;
+ if (arena) {
+ buf = malloc((size_t)nodes * sizeof *buf);
+ if (!buf) return 3;
+ }
+ for (k = 0; k < reps; k++) {
+ if (arena) {
+ node *root;
+ bump = buf;
+ root = make_at(D);
+ r = check(root);
+ __asm__ __volatile__("" : "+r"(r) : "r"(root) : "memory");
+ } else {
+ node *root = make(D);
+ r = check(root);
+ __asm__ __volatile__("" : "+r"(r) : "r"(root) : "memory");
+ destroy(root);
+ }
+ }
+ if (r != EXPECT) {
+ fprintf(stderr, "bad %d\n", r);
+ return 1;
+ }
+ printf("%d\n", r);
+ free(buf);
+ return 0;
+}