From d59e82c4a098f4e3987871fae0fbd6347b64b1f2 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 15 Jun 2012 09:50:06 -0700 Subject: Add a hash collision benchmark. --- configure.py | 21 ++++++++++----------- src/hash_collision_bench.cc | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 src/hash_collision_bench.cc diff --git a/configure.py b/configure.py index 7839dae..9eb2a48 100755 --- a/configure.py +++ b/configure.py @@ -314,21 +314,20 @@ n.newline() all_targets += ninja_test -n.comment('Perftest executables.') +n.comment('Ancilliary executables.') objs = cxx('parser_perftest') -parser_perftest = n.build(binary('parser_perftest'), 'link', objs, - implicit=ninja_lib, - variables=[('libs', libs)]) +all_targets += n.build(binary('parser_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) objs = cxx('build_log_perftest') -build_log_perftest = n.build(binary('build_log_perftest'), 'link', objs, - implicit=ninja_lib, - variables=[('libs', libs)]) +all_targets += n.build(binary('build_log_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) objs = cxx('canon_perftest') -canon_perftest = n.build(binary('canon_perftest'), 'link', objs, - implicit=ninja_lib, - variables=[('libs', libs)]) +all_targets += n.build(binary('canon_perftest'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) +objs = cxx('hash_collision_bench') +all_targets += n.build(binary('hash_collision_bench'), 'link', objs, + implicit=ninja_lib, variables=[('libs', libs)]) n.newline() -all_targets += parser_perftest + build_log_perftest + canon_perftest n.comment('Generate a graph using the "graph" tool.') n.rule('gendot', diff --git a/src/hash_collision_bench.cc b/src/hash_collision_bench.cc new file mode 100644 index 0000000..d9b09d9 --- /dev/null +++ b/src/hash_collision_bench.cc @@ -0,0 +1,43 @@ +#include "build_log.h" + +int random(int low, int high) { + return int(low + (rand() / double(RAND_MAX)) * (high - low) + 0.5); +} + +void RandomCommand(char** s) { + int len = random(5, 100); + *s = new char[len]; + for (int i = 0; i < len; ++i) + (*s)[i] = random(32, 127); +} + +int main() { + const int N = 20 * 1000 * 1000; + + // Leak these, else 10% of the runtime is spent destroying strings. + char** commands = new char*[N]; + pair* hashes = new pair[N]; + + srand(time(NULL)); + + for (int i = 0; i < N; ++i) { + RandomCommand(&commands[i]); + hashes[i] = make_pair(BuildLog::LogEntry::HashCommand(commands[i]), i); + } + + sort(hashes, hashes + N); + + int num_collisions = 0; + for (int i = 1; i < N; ++i) { + if (hashes[i - 1].first == hashes[i].first) { + if (strcmp(commands[hashes[i - 1].second], + commands[hashes[i].second]) != 0) { + printf("collision!\n string 1: '%s'\n string 2: '%s'\n", + commands[hashes[i - 1].second], + commands[hashes[i].second]); + num_collisions++; + } + } + } + printf("\n\n%d collisions after %d runs\n", num_collisions, N); +} -- cgit v0.12