summaryrefslogtreecommitdiff
path: root/tests/search_index_benchmark.c
blob: f17335a12bcfe67342b0c7feceef4348ebcb3d11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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;
}