15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2009 The RE2 Authors. All Rights Reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// license that can be found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/util.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/flags.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/benchmark.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "re2/re2.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DEFINE_string(test_tmpdir, "/var/tmp", "temp directory"); 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Benchmark; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace re2; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static Benchmark* benchmarks[10000]; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int nbenchmarks; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Benchmark::Register() { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) benchmarks[nbenchmarks] = this; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(lo < 1) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lo = 1; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(hi < lo) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hi = lo; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nbenchmarks++; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 nsec() { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval tv; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(gettimeofday(&tv, 0) < 0) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (int64)tv.tv_sec*1000*1000*1000 + tv.tv_usec*1000; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 bytes; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 ns; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 t0; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 items; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetBenchmarkBytesProcessed(long long x) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes = x; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StopBenchmarkTiming() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(t0 != 0) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns += nsec() - t0; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t0 = 0; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StartBenchmarkTiming() { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(t0 == 0) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t0 = nsec(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetBenchmarkItemsProcessed(int n) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items = n; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BenchmarkMemoryUsage() { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rsc): Implement. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NumCPUs() { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void runN(Benchmark *b, int n, int siz) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes = 0; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) items = 0; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = 0; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t0 = nsec(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(b->fn) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->fn(n); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if(b->fnr) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) b->fnr(n, siz); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "%s: missing function\n", b->name); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exit(2); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(t0 != 0) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns += nsec() - t0; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int round(int n) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int base = 1; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(base*10 < n) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base *= 10; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(n < 2*base) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2*base; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(n < 5*base) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 5*base; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 10*base; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunBench(Benchmark* b, int nthread, int siz) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int n, last; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rsc): Threaded benchmarks. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(nthread != 1) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run once in case it's expensive 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 1; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) runN(b, n, siz); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while(ns < (int)1e9 && n < (int)1e9) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = n; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ns/n == 0) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 1e9; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = 1e9 / (ns/n); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = max(last+1, min(n+n/2, 100*last)); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) n = round(n); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) runN(b, n, siz); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char mb[100]; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char suf[100]; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mb[0] = '\0'; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) suf[0] = '\0'; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(ns > 0 && bytes > 0) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(mb, sizeof mb, "\t%7.2f MB/s", ((double)bytes/1e6)/((double)ns/1e9)); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(b->fnr || b->lo != b->hi) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(siz >= (1<<20)) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(suf, sizeof suf, "/%dM", siz/(1<<20)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if(siz >= (1<<10)) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(suf, sizeof suf, "/%dK", siz/(1<<10)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snprintf(suf, sizeof suf, "/%d", siz); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s%s\t%8lld\t%10lld ns/op%s\n", b->name, suf, (long long)n, (long long)ns/n, mb); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fflush(stdout); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int match(const char* name, int argc, const char** argv) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(argc == 1) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(int i = 1; i < argc; i++) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(RE2::PartialMatch(name, argv[i])) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int main(int argc, const char** argv) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(int i = 0; i < nbenchmarks; i++) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Benchmark* b = benchmarks[i]; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if(match(b->name, argc, argv)) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(int j = b->threadlo; j <= b->threadhi; j++) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(int k = max(b->lo, 1); k <= max(b->hi, 1); k<<=1) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunBench(b, j, k); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 154