summaryrefslogtreecommitdiff
path: root/benchmarks/hist_bench.c
diff options
context:
space:
mode:
authorBerke Güzel <wenekar1@gmail.com>2026-10-12 17:49:34 +0300
committerBerke Güzel <wenekar1@gmail.com>2026-10-12 17:49:34 +0300
commit4384435941b8c7658856b381d071aee2e0035e89 (patch)
tree5ece99c3dd1decb8ec3fd404c0ece2b5865a552a /benchmarks/hist_bench.c
term: move the term core to subprojects/term
The core now builds, tests, and benchmarks alone, as a Meson subproject with no dependency on the main tree. - include/term/ holds term.h and the header-only unicode/. src/ holds the core and its private headers. The main tree gets only include/term through term_dep, so it cannot reach a private header. - The term tests, the term benchmarks, the Kitty parser suite, and tools/amalgamate.py and tools/generate_unicode.py move with it. The tests run as term:<name>. - The main build passes its -march (arch_flag) and b_ndebug to the subproject. A directory configured before this commit needs meson configure -Dterm:arch_flag=-march=... once. - The term tests compile with -UNDEBUG. They do work inside assert. - The subproject exports term_test_dep with term_api.h, for the main tree's render, thumbnail, color, and selection tests. - The Kitty bridge used struct vector2i and has not compiled since the public API redesign. It builds again. 2 of its 14 tests fail: REP after a tab, and a cursor report after a resize. - dirgraph.py drops the term and unicode layers. Its self-test uses pty. - The symbols test ignores the __odr_asan symbols that ASan adds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'benchmarks/hist_bench.c')
-rw-r--r--benchmarks/hist_bench.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/benchmarks/hist_bench.c b/benchmarks/hist_bench.c
new file mode 100644
index 0000000..2cf5608
--- /dev/null
+++ b/benchmarks/hist_bench.c
@@ -0,0 +1,93 @@
+#include "hist.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static double now(void)
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return ts.tv_sec + ts.tv_nsec * 1e-9;
+}
+
+/* Rows shaped like the term-write-bench lines that scroll into history. */
+static int make_row(const char *name, struct cell *row)
+{
+ struct cell d = { ' ', TERM_COLOR_FG, TERM_COLOR_BG, 0, 0 };
+ int n = 0;
+ if (!strcmp(name, "ascii-row")) {
+ const char *s = "The quick brown fox jumps over the lazy dog. 0123456789";
+ for (; s[n]; n++) {
+ row[n] = d;
+ row[n].c = (uint8_t)s[n];
+ }
+ } else if (!strcmp(name, "cjk-row")) {
+ for (int i = 0; i < 23; i++) {
+ row[n] = d;
+ row[n].c = 0x65e5 + (uint32_t)i;
+ row[n++].flags = CELL_WIDE;
+ row[n] = d;
+ row[n].c = 0;
+ row[n++].flags = CELL_TRAIL;
+ }
+ } else if (!strcmp(name, "colors-row")) {
+ const char *s = "red RGB";
+ for (; s[n]; n++) {
+ row[n] = d;
+ row[n].c = (uint8_t)s[n];
+ if (n < 3)
+ row[n].fg = term_color_index(1);
+ if (n > 3)
+ row[n].fg = term_color_rgb(12, 34, 56);
+ }
+ } else if (!strcmp(name, "fg-char-row")) {
+ for (; n < 120; n++) {
+ row[n] = d;
+ row[n].c = 'a' + (uint32_t)(n % 26);
+ row[n].fg = term_color_rgb((uint8_t)n, (uint8_t)(n * 3), (uint8_t)(n * 7));
+ }
+ }
+ return n;
+}
+
+int main(int argc, char **argv)
+{
+ int iterations = argc > 1 ? atoi(argv[1]) : 10000000;
+ struct hist h;
+ if (!term_hist_init(&h, 10000, 8 * 1024 * 1024)) {
+ fprintf(stderr, "failed to initialize hist\n");
+ return EXIT_FAILURE;
+ }
+
+ const char *line = "abcdefghijklmnopqrstuvwxyz\n";
+ int len = (int)strlen(line);
+ for (int i = 0; i < 10000; i++)
+ term_hist_push_ascii(&h, line, len, NULL, false);
+ double t0 = now();
+ for (int i = 0; i < iterations; i++)
+ term_hist_push_ascii(&h, line, len, NULL, false);
+ double elapsed = now() - t0;
+ printf("%-12s %6.2f ns/line %.2f GiB/s (%d B/line)\n", "ascii",
+ elapsed * 1e9 / iterations,
+ (double)iterations * len / (1024.0 * 1024.0 * 1024.0) / elapsed, len);
+ term_hist_free(&h);
+
+ static const char *rows[] = { "ascii-row", "cjk-row", "colors-row", "fg-char-row" };
+ for (size_t k = 0; k < sizeof(rows) / sizeof(rows[0]); k++) {
+ struct cell row[128];
+ int n = make_row(rows[k], row);
+ int iters = iterations / 4;
+ if (!term_hist_init(&h, 4096, 0))
+ return EXIT_FAILURE;
+ for (int i = 0; i < 10000; i++)
+ term_hist_push_row(&h, row, n, false, NULL);
+ t0 = now();
+ for (int i = 0; i < iters; i++)
+ term_hist_push_row(&h, row, n, false, NULL);
+ elapsed = now() - t0;
+ printf("%-12s %6.2f ns/row (%d cells)\n", rows[k], elapsed * 1e9 / iters, n);
+ term_hist_free(&h);
+ }
+ return EXIT_SUCCESS;
+}