summaryrefslogtreecommitdiff
path: root/tests/search_index_benchmark.c
diff options
context:
space:
mode:
authortanaka takashi <isazaka@gmail.com>2026-06-30 23:55:29 +0900
committertanaka takashi <isazaka@gmail.com>2026-06-30 23:55:29 +0900
commite3db01cd487c5b666366885367c8bfff4a6a09da (patch)
treec5b24d79daeb017d87d3520b82d1de31358e5974 /tests/search_index_benchmark.c
parentac4dd6ad07d2d9048c3177dc4f3df42146268233 (diff)
検索インデックスのhash table化
Diffstat (limited to 'tests/search_index_benchmark.c')
-rw-r--r--tests/search_index_benchmark.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/tests/search_index_benchmark.c b/tests/search_index_benchmark.c
new file mode 100644
index 0000000..f17335a
--- /dev/null
+++ b/tests/search_index_benchmark.c
@@ -0,0 +1,110 @@
+#include "domain/message.h"
+#include "domain/search.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <psapi.h>
+#endif
+
+#include "base/allocator.h"
+
+static double
+now_milliseconds(void)
+{
+ struct timespec value;
+ timespec_get(&value, TIME_UTC);
+ return (double)value.tv_sec * 1000.0 + (double)value.tv_nsec / 1000000.0;
+}
+
+static uint64_t
+peak_working_set(void)
+{
+#ifdef _WIN32
+ PROCESS_MEMORY_COUNTERS counters;
+ if (GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
+ {
+ return (uint64_t)counters.PeakWorkingSetSize;
+ }
+#endif
+ return 0;
+}
+
+static char *
+make_content(size_t size)
+{
+ static const char alphabet[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
+ uint32_t state = UINT32_C(0x9e3779b9);
+ char *content;
+ size_t position;
+ if (size == SIZE_MAX)
+ {
+ return NULL;
+ }
+ content = malloc(size + 1);
+ if (!content)
+ {
+ return NULL;
+ }
+ for (position = 0; position < size; ++position)
+ {
+ state = state * UINT32_C(1664525) + UINT32_C(1013904223);
+ content[position] = alphabet[state % (sizeof(alphabet) - 1)];
+ }
+ content[size] = '\0';
+ return content;
+}
+
+int
+main(int argc, char **argv)
+{
+ tiny_message_t message;
+ size_t size, iterations, iteration;
+ char *content;
+ double started, elapsed;
+ if (argc != 3)
+ {
+ fprintf(stderr, "usage: %s SIZE_BYTES ITERATIONS\n", argv[0]);
+ return 2;
+ }
+ size = (size_t)strtoull(argv[1], NULL, 10);
+ iterations = (size_t)strtoull(argv[2], NULL, 10);
+ if (size == 0 || size > TINY_CONTENT_MAX || iterations == 0)
+ {
+ fprintf(stderr, "size or iterations is out of range\n");
+ return 2;
+ }
+ content = make_content(size);
+ if (!content)
+ {
+ return 1;
+ }
+ tiny_message_init(&message);
+ message.content = content;
+ started = now_milliseconds();
+ for (iteration = 0; iteration < iterations; ++iteration)
+ {
+ tiny_search_index_t *index = tiny_search_index_create();
+ if (!index || !tiny_search_index_add(index, &message, 0))
+ {
+ tiny_search_index_free(index);
+ free(content);
+ return 1;
+ }
+ tiny_search_index_free(index);
+ }
+ elapsed = now_milliseconds() - started;
+ printf("{\"size_bytes\":%zu,\"iterations\":%zu,\"total_ms\":%.3f,"
+ "\"mean_ms\":%.3f,\"peak_working_set_bytes\":%llu}\n",
+ size,
+ iterations,
+ elapsed,
+ elapsed / (double)iterations,
+ (unsigned long long)peak_working_set());
+ free(content);
+ return tiny_allocator_outstanding() == 0 ? 0 : 1;
+}