1 /* Simple speed tests using strset code.
3 * Results on my 32 bit Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz, gcc 4.5.2:
4 * Run 100 times: Min-Max(Avg)
5 #01: Initial insert: 212-219(214)
6 #02: Initial lookup (match): 161-169(162)
7 #03: Initial lookup (miss): 157-163(158)
8 #04: Initial lookup (random): 450-479(453)
9 #05: Initial delete all: 126-137(128)
10 #06: Initial re-inserting: 193-198(194)
11 #07: Deleting first half: 99-102(99)
12 #08: Adding (a different) half: 143-154(144)
13 #09: Lookup after half-change (match): 183-189(184)
14 #10: Lookup after half-change (miss): 198-212(199)
15 #11: Churn 1: 274-282(276)
16 #12: Churn 2: 279-296(282)
17 #13: Churn 3: 278-294(280)
18 #14: Post-Churn lookup (match): 170-180(171)
19 #15: Post-Churn lookup (miss): 175-186(176)
20 #16: Post-Churn lookup (random): 522-534(525)
22 #include <ccan/str_talloc/str_talloc.h>
23 #include <ccan/grab_file/grab_file.h>
24 #include <ccan/talloc/talloc.h>
25 #include <ccan/time/time.h>
26 #include <ccan/strset/strset.c>
34 /* Nanoseconds per operation */
35 static size_t normalize(const struct timeval
*start
,
36 const struct timeval
*stop
,
41 timersub(stop
, start
, &diff
);
43 /* Floating point is more accurate here. */
44 return (double)(diff
.tv_sec
* 1000000 + diff
.tv_usec
)
48 int main(int argc
, char *argv
[])
51 struct timeval start
, stop
;
53 char **words
, **misswords
;
55 words
= strsplit(NULL
, grab_file(NULL
,
56 argv
[1] ? argv
[1] : "/usr/share/dict/words",
59 num
= talloc_array_length(words
) - 1;
60 printf("%zu words\n", num
);
62 /* Append and prepend last char for miss testing. */
63 misswords
= talloc_array(words
, char *, num
);
64 for (i
= 0; i
< num
; i
++) {
67 lastc
= words
[i
][strlen(words
[i
])-1];
70 misswords
[i
] = talloc_asprintf(misswords
, "%c%s%c%c",
71 lastc
, words
[i
], lastc
, lastc
);
74 printf("#01: Initial insert: ");
77 for (i
= 0; i
< num
; i
++)
78 strset_set(&set
, words
[i
]);
80 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
83 printf("Nodes allocated: %zu (%zu bytes)\n",
84 allocated
, allocated
* sizeof(critbit0_node
));
87 printf("#02: Initial lookup (match): ");
90 for (i
= 0; i
< num
; i
++)
91 if (!strset_test(&set
, words
[i
]))
94 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
96 printf("#03: Initial lookup (miss): ");
99 for (i
= 0; i
< num
; i
++) {
100 if (strset_test(&set
, misswords
[i
]))
104 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
106 /* Lookups in order are very cache-friendly for judy; try random */
107 printf("#04: Initial lookup (random): ");
110 for (i
= 0, j
= 0; i
< num
; i
++, j
= (j
+ 10007) % num
)
111 if (!strset_test(&set
, words
[j
]))
114 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
116 printf("#05: Initial delete all: ");
119 for (i
= 0; i
< num
; i
++)
120 if (!strset_clear(&set
, words
[i
]))
123 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
125 printf("#06: Initial re-inserting: ");
128 for (i
= 0; i
< num
; i
++)
129 strset_set(&set
, words
[i
]);
131 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
133 printf("#07: Deleting first half: ");
136 for (i
= 0; i
< num
; i
+=2)
137 if (!strset_clear(&set
, words
[i
]))
140 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
142 printf("#08: Adding (a different) half: ");
146 for (i
= 0; i
< num
; i
+=2)
147 strset_set(&set
, misswords
[i
]);
149 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
151 printf("#09: Lookup after half-change (match): ");
154 for (i
= 1; i
< num
; i
+=2)
155 if (!strset_test(&set
, words
[i
]))
157 for (i
= 0; i
< num
; i
+=2) {
158 if (!strset_test(&set
, misswords
[i
]))
162 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
164 printf("#10: Lookup after half-change (miss): ");
167 for (i
= 0; i
< num
; i
+=2)
168 if (strset_test(&set
, words
[i
]))
170 for (i
= 1; i
< num
; i
+=2) {
171 if (strset_test(&set
, misswords
[i
]))
175 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
177 /* Hashtables with delete markers can fill with markers over time.
178 * so do some changes to see how it operates in long-term. */
179 printf("#11: Churn 1: ");
181 for (j
= 0; j
< num
; j
+=2) {
182 if (!strset_clear(&set
, misswords
[j
]))
184 if (!strset_set(&set
, words
[j
]))
188 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
190 printf("#12: Churn 2: ");
192 for (j
= 1; j
< num
; j
+=2) {
193 if (!strset_clear(&set
, words
[j
]))
195 if (!strset_set(&set
, misswords
[j
]))
199 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
201 printf("#13: Churn 3: ");
203 for (j
= 1; j
< num
; j
+=2) {
204 if (!strset_clear(&set
, misswords
[j
]))
206 if (!strset_set(&set
, words
[j
]))
210 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
212 /* Now it's back to normal... */
213 printf("#14: Post-Churn lookup (match): ");
216 for (i
= 0; i
< num
; i
++)
217 if (!strset_test(&set
, words
[i
]))
220 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
222 printf("#15: Post-Churn lookup (miss): ");
225 for (i
= 0; i
< num
; i
++) {
226 if (strset_test(&set
, misswords
[i
]))
230 printf(" %zu ns\n", normalize(&start
, &stop
, num
));
232 /* Lookups in order are very cache-friendly for judy; try random */
233 printf("#16: Post-Churn lookup (random): ");
236 for (i
= 0, j
= 0; i
< num
; i
++, j
= (j
+ 10007) % num
)
237 if (!strset_test(&set
, words
[j
]))
240 printf(" %zu ns\n", normalize(&start
, &stop
, num
));