1 /* EINA - EFL data type library
2 * Copyright (C) 2008 Cedric Bail
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library;
16 * if not, see <http://www.gnu.org/licenses/>.
28 #ifdef EINA_BENCH_HAVE_GLIB
32 #include "Evas_Data.h"
33 #include "Ecore_Data.h"
35 #include "eina_hash.h"
36 #include "eina_array.h"
37 #include "eina_bench.h"
38 #include "eina_rbtree.h"
39 #include "eina_convert.h"
42 // Hash function for a byte array.
43 uint64_t CityHash64(const char *buf, size_t len);
46 _eina_string_key_length(const char *key)
51 return (int)strlen(key) + 1;
55 _eina_string_key_cmp(const char *key1, __UNUSED__ int key1_length,
56 const char *key2, __UNUSED__ int key2_length)
58 return strcmp(key1, key2);
63 typedef struct _Eina_Bench_Rbtree Eina_Bench_Rbtree;
64 struct _Eina_Bench_Rbtree
71 static Eina_Rbtree_Direction
72 _eina_bench_rbtree_cmp(const Eina_Bench_Rbtree *left,
73 const Eina_Bench_Rbtree *right,
74 __UNUSED__ void *data)
77 return EINA_RBTREE_RIGHT;
80 return EINA_RBTREE_LEFT;
82 return strcmp(left->key,
83 right->key) < 0 ? EINA_RBTREE_LEFT : EINA_RBTREE_RIGHT;
87 _eina_bench_rbtree_key(const Eina_Bench_Rbtree *node,
90 __UNUSED__ void *data)
92 return strncmp(node->key, key, length);
96 _eina_bench_rbtree_free(Eina_Rbtree *node, __UNUSED__ void *data)
102 eina_bench_lookup_rbtree(int request)
104 Eina_Rbtree *root = NULL;
108 for (i = 0; i < request; ++i)
110 Eina_Bench_Rbtree *tmp;
112 tmp = malloc(sizeof (Eina_Bench_Rbtree));
117 eina_convert_itoa(i, tmp->key);
119 root = eina_rbtree_inline_insert(root,
121 EINA_RBTREE_CMP_NODE_CB(
122 _eina_bench_rbtree_cmp),
128 for (j = 0; j < 200; ++j)
129 for (i = 0; i < request; ++i)
134 eina_convert_itoa(rand() % request, tmp_key);
136 tmp = eina_rbtree_inline_lookup(root,
139 EINA_RBTREE_CMP_KEY_CB(
140 _eina_bench_rbtree_key),
142 /* Suppress warnings as we really don't want to do anything. */
146 eina_rbtree_delete(root, EINA_RBTREE_FREE_CB(_eina_bench_rbtree_free), NULL);
150 eina_bench_lookup_murmur(int request)
152 Eina_Hash *hash = NULL;
157 hash = eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
158 EINA_KEY_CMP(_eina_string_key_cmp),
159 EINA_KEY_HASH(eina_hash_murmur3),
163 for (i = 0; i < (unsigned int)request; ++i)
167 tmp_val = malloc(sizeof (int));
172 eina_convert_itoa(i, tmp_key);
175 eina_hash_add(hash, tmp_key, tmp_val);
180 for (j = 0; j < 200; ++j)
181 for (i = 0; i < (unsigned int)request; ++i)
185 eina_convert_itoa(rand() % request, tmp_key);
186 tmp_val = eina_hash_find(hash, tmp_key);
189 eina_hash_free(hash);
192 #ifdef CITYHASH_BENCH
194 eina_bench_lookup_cityhash(int request)
196 Eina_Hash *hash = NULL;
201 hash = eina_hash_new(EINA_KEY_LENGTH(_eina_string_key_length),
202 EINA_KEY_CMP(_eina_string_key_cmp),
203 EINA_KEY_HASH(CityHash64),
207 for (i = 0; i < (unsigned int)request; ++i)
211 tmp_val = malloc(sizeof (int));
216 eina_convert_itoa(i, tmp_key);
219 eina_hash_add(hash, tmp_key, tmp_val);
224 for (j = 0; j < 200; ++j)
225 for (i = 0; i < (unsigned int)request; ++i)
229 eina_convert_itoa(rand() % request, tmp_key);
230 tmp_val = eina_hash_find(hash, tmp_key);
233 eina_hash_free(hash);
238 eina_bench_lookup_superfast(int request)
240 Eina_Hash *hash = NULL;
245 hash = eina_hash_string_superfast_new(free);
247 for (i = 0; i < (unsigned int)request; ++i)
251 tmp_val = malloc(sizeof (int));
256 eina_convert_itoa(i, tmp_key);
259 eina_hash_add(hash, tmp_key, tmp_val);
264 for (j = 0; j < 200; ++j)
265 for (i = 0; i < (unsigned int)request; ++i)
269 eina_convert_itoa(rand() % request, tmp_key);
270 tmp_val = eina_hash_find(hash, tmp_key);
273 eina_hash_free(hash);
277 eina_bench_lookup_djb2(int request)
279 Eina_Hash *hash = NULL;
284 hash = eina_hash_string_djb2_new(free);
286 for (i = 0; i < (unsigned int)request; ++i)
290 tmp_val = malloc(sizeof (int));
295 eina_convert_itoa(i, tmp_key);
298 eina_hash_add(hash, tmp_key, tmp_val);
303 for (j = 0; j < 200; ++j)
304 for (i = 0; i < (unsigned int)request; ++i)
308 eina_convert_itoa(rand() % request, tmp_key);
310 tmp_val = eina_hash_find(hash, tmp_key);
313 eina_hash_free(hash);
316 typedef struct _Eina_Bench_DJB2 Eina_Bench_DJB2;
317 struct _Eina_Bench_DJB2
324 eina_bench_lookup_djb2_inline(int request)
326 Eina_Hash *hash = NULL;
327 Eina_Bench_DJB2 *elm;
331 hash = eina_hash_string_djb2_new(free);
333 for (i = 0; i < (unsigned int)request; ++i)
337 elm = malloc(sizeof (Eina_Bench_DJB2) + 10);
341 elm->key = (char *)(elm + 1);
343 length = eina_convert_itoa(i, elm->key) + 1;
346 eina_hash_direct_add_by_hash(hash, elm->key, length,
347 eina_hash_djb2(elm->key, length), elm);
352 for (j = 0; j < 200; ++j)
353 for (i = 0; i < (unsigned int)request; ++i)
358 length = eina_convert_itoa(rand() % request, tmp_key) + 1;
361 eina_hash_find_by_hash(hash, tmp_key, length,
362 eina_hash_djb2(tmp_key, length));
365 eina_hash_free(hash);
368 #ifdef EINA_BENCH_HAVE_GLIB
369 typedef struct _Eina_Bench_Glib Eina_Bench_Glib;
370 struct _Eina_Bench_Glib
377 eina_bench_lookup_ghash(int request)
379 Eina_Bench_Glib *elm;
384 hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, free);
386 for (i = 0; i < (unsigned int)request; ++i)
388 elm = malloc(sizeof (Eina_Bench_Glib) + 10);
392 elm->key = (char *)(elm + 1);
394 eina_convert_itoa(i, elm->key);
397 g_hash_table_insert(hash, elm->key, elm);
402 for (j = 0; j < 200; ++j)
403 for (i = 0; i < (unsigned int)request; ++i)
407 eina_convert_itoa(rand() % request, tmp_key);
409 elm = g_hash_table_lookup(hash, tmp_key);
412 g_hash_table_destroy(hash);
417 eina_bench_lookup_evas(int request)
419 Evas_Hash *hash = NULL;
420 Eina_Array *array = NULL;
422 Eina_Array_Iterator it;
426 array = eina_array_new(10000);
428 for (i = 0; i < (unsigned int)request; ++i)
432 tmp_val = malloc(sizeof (int));
437 eina_convert_itoa(i, tmp_key);
440 hash = evas_hash_add(hash, tmp_key, tmp_val);
442 eina_array_push(array, tmp_val);
447 for (j = 0; j < 200; ++j)
448 for (i = 0; i < (unsigned int)request; ++i)
452 eina_convert_itoa(rand() % request, tmp_key);
454 tmp_val = evas_hash_find(hash, tmp_key);
457 evas_hash_free(hash);
459 EINA_ARRAY_ITER_NEXT(array, i, tmp_val, it)
462 eina_array_free(array);
465 typedef struct _Eina_Bench_Ecore Eina_Bench_Ecore;
466 struct _Eina_Bench_Ecore
473 eina_bench_lookup_ecore(int request)
475 Ecore_Hash *hash = NULL;
476 Eina_Bench_Ecore *elm;
480 hash = ecore_hash_new(ecore_str_hash, ecore_str_compare);
482 ecore_hash_free_key_cb_set(hash, NULL);
483 ecore_hash_free_value_cb_set(hash, free);
485 for (i = 0; i < (unsigned int)request; ++i)
487 elm = malloc(sizeof (Eina_Bench_Ecore) + 10);
491 elm->key = (char *)(elm + 1);
492 eina_convert_itoa(i, elm->key);
495 ecore_hash_set(hash, elm->key, elm);
500 for (j = 0; j < 200; ++j)
501 for (i = 0; i < (unsigned int)request; ++i)
505 eina_convert_itoa(rand() % request, tmp_key);
507 elm = ecore_hash_get(hash, tmp_key);
510 ecore_hash_destroy(hash);
513 void eina_bench_hash(Eina_Benchmark *bench)
515 eina_benchmark_register(bench, "superfast-lookup",
517 eina_bench_lookup_superfast), 10, 10000, 10);
518 eina_benchmark_register(bench, "djb2-lookup",
520 eina_bench_lookup_djb2), 10, 10000, 10);
521 eina_benchmark_register(bench, "djb2-lookup-inline",
523 eina_bench_lookup_djb2_inline), 10, 10000, 10);
524 eina_benchmark_register(bench, "murmur",
526 eina_bench_lookup_murmur), 10, 10000, 10);
527 #ifdef CITYHASH_BENCH
528 eina_benchmark_register(bench, "cityhash",
530 eina_bench_lookup_cityhash), 10, 10000, 10);
532 eina_benchmark_register(bench, "rbtree",
534 eina_bench_lookup_rbtree), 10, 10000, 10);
535 #ifdef EINA_BENCH_HAVE_GLIB
536 eina_benchmark_register(bench, "ghash-lookup",
538 eina_bench_lookup_ghash), 10, 10000, 10);
540 eina_benchmark_register(bench, "evas-lookup",
542 eina_bench_lookup_evas), 10, 10000, 10);
543 eina_benchmark_register(bench, "ecore-lookup",
545 eina_bench_lookup_ecore), 10, 10000, 10);