Update benchmark
This commit is contained in:
1 parent
66b6677afa
commit
feaac16804
5 files changed
+204
-52
No files matched your search
@@ -2,32 +2,42 @@
|
||||
#error "Please define COUNT"
|
||||
#endif
|
||||
|
||||
#include "cmc/hashmap.h"
|
||||
#include "murmurhash.h"
|
||||
|
||||
CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hmi32, hashmapi32, , int32_t, int32_t))
|
||||
CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hmi32, hashmapi32, , int32_t, int32_t))
|
||||
#include "macro_collections.h"
|
||||
|
||||
int cmp(int32_t a, int32_t b)
|
||||
#include "../../util/twister.c"
|
||||
|
||||
CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hm, hashmap, , uint64_t, uint64_t))
|
||||
CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hm, hashmap, , uint64_t, uint64_t))
|
||||
|
||||
int cmp(uint64_t a, uint64_t b)
|
||||
{
|
||||
return (a > b) - (a < b);
|
||||
}
|
||||
|
||||
size_t hash(int32_t a)
|
||||
// size_t hash(uint64_t a)
|
||||
// {
|
||||
// size_t x = (size_t)a;
|
||||
// x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
// x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
// x = (x >> 16) ^ x;
|
||||
// return x;
|
||||
// }
|
||||
|
||||
size_t hash(uint64_t k)
|
||||
{
|
||||
size_t x = (size_t)a;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
x = (x >> 16) ^ x;
|
||||
return x;
|
||||
static size_t seed = 211106232532969;
|
||||
return MurMurHash(&k, sizeof(k), seed);
|
||||
}
|
||||
|
||||
struct hashmapi32_fkey *fkey = &(struct hashmapi32_fkey) {
|
||||
struct hashmap_fkey *fkey = &(struct hashmap_fkey) {
|
||||
.cmp = cmp,
|
||||
.hash = hash,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct hashmapi32_fval *fval = &(struct hashmapi32_fval) {
|
||||
struct hashmap_fval *fval = &(struct hashmap_fval) {
|
||||
.cmp = cmp,
|
||||
.hash = hash,
|
||||
NULL
|
||||
@@ -35,12 +45,18 @@ struct hashmapi32_fval *fval = &(struct hashmapi32_fval) {
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct hashmapi32 *map = hmi32_new(COUNT, 0.6, fkey, fval);
|
||||
mt_state tw;
|
||||
twist_init(&tw, 50331653);
|
||||
|
||||
for (int32_t i = 0; i < COUNT; i++)
|
||||
hmi32_insert(map, i, i);
|
||||
struct hashmap *map = hm_new(COUNT, 0.6, fkey, fval);
|
||||
|
||||
hmi32_free(map);
|
||||
for (uint64_t i = 0; i < COUNT; i++)
|
||||
{
|
||||
uint64_t v = twist_uint64(&tw);
|
||||
hm_insert(map, v, v);
|
||||
}
|
||||
|
||||
hm_free(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef COUNT
|
||||
#error "Please define COUNT"
|
||||
#endif
|
||||
|
||||
#include "murmurhash.h"
|
||||
|
||||
#include "macro_collections.h"
|
||||
|
||||
#include "../../util/twister.c"
|
||||
|
||||
C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , uint64_t, uint64_t))
|
||||
|
||||
int cmp(uint64_t a, uint64_t b)
|
||||
{
|
||||
return (a > b) - (a < b);
|
||||
}
|
||||
|
||||
// size_t hash(uint64_t a)
|
||||
// {
|
||||
// size_t x = (size_t)a;
|
||||
// x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
// x = ((x >> 16) ^ x) * 0x45d9f3b;
|
||||
// x = (x >> 16) ^ x;
|
||||
// return x;
|
||||
// }
|
||||
|
||||
size_t hash(uint64_t k)
|
||||
{
|
||||
static size_t seed = 211106232532969;
|
||||
return MurMurHash(&k, sizeof(k), seed);
|
||||
}
|
||||
|
||||
struct hashmultimap_fkey *fkey = &(struct hashmultimap_fkey) {
|
||||
.cmp = cmp,
|
||||
.hash = hash,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct hashmultimap_fval *fval = &(struct hashmultimap_fval) {
|
||||
.cmp = cmp,
|
||||
.hash = hash,
|
||||
NULL
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mt_state tw;
|
||||
twist_init(&tw, 50331653);
|
||||
|
||||
struct hashmultimap *map = hmm_new(COUNT, 0.6, fkey, fval);
|
||||
|
||||
for (uint64_t i = 0; i < COUNT; i++)
|
||||
{
|
||||
uint64_t v = twist_uint64(&tw);
|
||||
hmm_insert(map, v, v);
|
||||
}
|
||||
|
||||
hmm_free(map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/hash_bytes.cc
|
||||
|
||||
#ifndef MURMURHASH
|
||||
#define MURMURHASH
|
||||
|
||||
#include <string.h>
|
||||
|
||||
inline size_t unaligned_load(const char *p)
|
||||
{
|
||||
size_t result;
|
||||
memcpy(&result, p, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
inline size_t load_bytes(const char *p, int n)
|
||||
{
|
||||
size_t result = 0;
|
||||
--n;
|
||||
do
|
||||
{
|
||||
result = (result << 8) + (unsigned char)(p[n]);
|
||||
} while (--n >= 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline size_t shift_mix(size_t v)
|
||||
{
|
||||
return v ^ (v >> 47);
|
||||
}
|
||||
|
||||
size_t MurMurHash(const void *ptr, size_t len, size_t seed)
|
||||
{
|
||||
static const size_t mul = (((size_t)0xc6a4a793UL) << 32UL) + (size_t)0x5bd1e995UL;
|
||||
const char *const buf = (const char *)(ptr);
|
||||
|
||||
// Remove the bytes not divisible by the sizeof(size_t). This
|
||||
// allows the main loop to process the data as 64-bit integers.
|
||||
const size_t len_aligned = len & ~(size_t)0x7;
|
||||
const char *const end = buf + len_aligned;
|
||||
size_t hash = seed ^ (len * mul);
|
||||
for (const char *p = buf; p != end; p += 8)
|
||||
{
|
||||
const size_t data = shift_mix(unaligned_load(p) * mul) * mul;
|
||||
hash ^= data;
|
||||
hash *= mul;
|
||||
}
|
||||
if ((len & 0x7) != 0)
|
||||
{
|
||||
const size_t data = load_bytes(end, len & 0x7);
|
||||
hash ^= data;
|
||||
hash *= mul;
|
||||
}
|
||||
hash = shift_mix(hash) * mul;
|
||||
hash = shift_mix(hash);
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif /* MURMURHASH */
|
||||
@@ -1,8 +1,10 @@
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import subprocess
|
||||
|
||||
ITERATIONS = 10
|
||||
COUNT = 20000000
|
||||
VERBOSE = False
|
||||
|
||||
NL = '\n'
|
||||
@@ -11,48 +13,45 @@ INCLUDE = "../../../src"
|
||||
CC = 'gcc'
|
||||
CCPP = 'g++' # LoL
|
||||
OPT = '-O3'
|
||||
COUNT = 2000000
|
||||
|
||||
print(f'Using {CC} compiler')
|
||||
|
||||
|
||||
def execute_command(commands):
|
||||
print(' '.join(commands))
|
||||
subprocess.run(commands, shell=True)
|
||||
|
||||
|
||||
# Common args
|
||||
args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS']
|
||||
|
||||
c_args = [CC, 'hashmap.c', '-o', 'hashmap.exe']
|
||||
map_args = [CC, 'hashmap.c', '-o', 'hashmap.exe']
|
||||
mmap_args = [CC, 'hashmultimap.c', '-o', 'hashmultimap.exe']
|
||||
cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}']
|
||||
|
||||
c_args.extend(args)
|
||||
map_args.extend(args)
|
||||
mmap_args.extend(args)
|
||||
cpp_args.extend(args)
|
||||
|
||||
subprocess.check_output(c_args)
|
||||
subprocess.check_output(cpp_args)
|
||||
execute_command(map_args)
|
||||
execute_command(mmap_args)
|
||||
execute_command(cpp_args)
|
||||
|
||||
total = 0
|
||||
for i in range(ITERATIONS):
|
||||
print(f'{i}...', end='')
|
||||
sys.stdout.flush()
|
||||
start_time = time.time()
|
||||
subprocess.call(['./hashmap.exe'])
|
||||
programs = ['hashmap.exe', 'hashmultimap.exe', 'unorderedmap.exe']
|
||||
|
||||
delta = time.time() - start_time
|
||||
total += delta
|
||||
for prog in programs:
|
||||
total = 0
|
||||
for i in range(ITERATIONS):
|
||||
print(f'{i}...', end='')
|
||||
sys.stdout.flush()
|
||||
start_time = time.time()
|
||||
subprocess.run(prog, shell=True)
|
||||
|
||||
if VERBOSE:
|
||||
print(f'({delta})')
|
||||
delta = time.time() - start_time
|
||||
total += delta
|
||||
|
||||
avg = int(((total / ITERATIONS) * 1e9) / COUNT)
|
||||
print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [hashmap.exe]{NL if VERBOSE else ""}')
|
||||
if VERBOSE:
|
||||
print(f'({delta})')
|
||||
|
||||
total = 0
|
||||
for i in range(ITERATIONS):
|
||||
print(f'{i}...', end='')
|
||||
sys.stdout.flush()
|
||||
start_time = time.time()
|
||||
subprocess.call(['./unorderedmap.exe'])
|
||||
|
||||
delta = time.time() - start_time
|
||||
total += delta
|
||||
|
||||
if VERBOSE:
|
||||
print(f'({delta})')
|
||||
|
||||
avg = int(((total / ITERATIONS) * 1e9) / COUNT)
|
||||
print(f'{"" if VERBOSE else NL}{total / ITERATIONS} seconds for {COUNT} -> AVG[{avg} ns] [unorderedmap.exe]{NL if VERBOSE else ""}')
|
||||
avg = total / ITERATIONS
|
||||
print(f'{"" if VERBOSE else NL}{avg} seconds for {COUNT} -> AVG[{int((avg * 1e9) / COUNT)} ns] [{prog}]{NL if VERBOSE else ""}')
|
||||
@@ -2,15 +2,33 @@
|
||||
#error "Please define COUNT"
|
||||
#endif
|
||||
|
||||
#include "murmurhash.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../util/twister.c"
|
||||
|
||||
struct IntHasher
|
||||
{
|
||||
std::size_t operator()(const uint64_t& k) const
|
||||
{
|
||||
static size_t seed = 211106232532969;
|
||||
return MurMurHash(&k, sizeof(k), seed);
|
||||
}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
std::unordered_map<int32_t, int32_t> map(COUNT);
|
||||
mt_state tw;
|
||||
twist_init(&tw, 50331653);
|
||||
|
||||
for (int32_t i = 0; i < COUNT; i++)
|
||||
map.insert({i, i});
|
||||
std::unordered_map<uint64_t, uint64_t, IntHasher> map(COUNT);
|
||||
|
||||
for (uint64_t i = 0; i < COUNT; i++)
|
||||
{
|
||||
uint64_t v = twist_uint64(&tw);
|
||||
map.insert({v, v});
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user