1ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj// Copyright 2009 The RE2 Authors. All Rights Reserved. 2ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj// Use of this source code is governed by a BSD-style 3ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj// license that can be found in the LICENSE file. 4887a11a609f3e61d2ae8fe4e67f176207715da7esewardj 5496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj#include "util/util.h" 6ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include "util/flags.h" 7ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include "util/benchmark.h" 8ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj#include "re2/re2.h" 9f8ed9d874a7b8651654591c68c6d431c758d787csewardj 10f8ed9d874a7b8651654591c68c6d431c758d787csewardjDEFINE_string(test_tmpdir, "/var/tmp", "temp directory"); 11f8ed9d874a7b8651654591c68c6d431c758d787csewardj 12f8ed9d874a7b8651654591c68c6d431c758d787csewardjusing testing::Benchmark; 13496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjusing namespace re2; 14f8ed9d874a7b8651654591c68c6d431c758d787csewardj 15f8ed9d874a7b8651654591c68c6d431c758d787csewardjstatic Benchmark* benchmarks[10000]; 16f8ed9d874a7b8651654591c68c6d431c758d787csewardjstatic int nbenchmarks; 17f8ed9d874a7b8651654591c68c6d431c758d787csewardj 18f8ed9d874a7b8651654591c68c6d431c758d787csewardjvoid Benchmark::Register() { 19f8ed9d874a7b8651654591c68c6d431c758d787csewardj benchmarks[nbenchmarks] = this; 20f8ed9d874a7b8651654591c68c6d431c758d787csewardj if(lo < 1) 21f8ed9d874a7b8651654591c68c6d431c758d787csewardj lo = 1; 22f8ed9d874a7b8651654591c68c6d431c758d787csewardj if(hi < lo) 23f8ed9d874a7b8651654591c68c6d431c758d787csewardj hi = lo; 24f8ed9d874a7b8651654591c68c6d431c758d787csewardj nbenchmarks++; 25f8ed9d874a7b8651654591c68c6d431c758d787csewardj} 26f8ed9d874a7b8651654591c68c6d431c758d787csewardj 27f8ed9d874a7b8651654591c68c6d431c758d787csewardjstatic int64 nsec() { 28f8ed9d874a7b8651654591c68c6d431c758d787csewardj struct timeval tv; 29f8ed9d874a7b8651654591c68c6d431c758d787csewardj if(gettimeofday(&tv, 0) < 0) 30f8ed9d874a7b8651654591c68c6d431c758d787csewardj return -1; 31f8ed9d874a7b8651654591c68c6d431c758d787csewardj return (int64)tv.tv_sec*1000*1000*1000 + tv.tv_usec*1000; 32f8ed9d874a7b8651654591c68c6d431c758d787csewardj} 33f8ed9d874a7b8651654591c68c6d431c758d787csewardj 34f8ed9d874a7b8651654591c68c6d431c758d787csewardjstatic int64 bytes; 35f8ed9d874a7b8651654591c68c6d431c758d787csewardjstatic int64 ns; 36887a11a609f3e61d2ae8fe4e67f176207715da7esewardjstatic int64 t0; 37887a11a609f3e61d2ae8fe4e67f176207715da7esewardjstatic int64 items; 38ac9af021b93dfe6f35c01d9c6fd15a3d67685843sewardj 39887a11a609f3e61d2ae8fe4e67f176207715da7esewardjvoid SetBenchmarkBytesProcessed(long long x) { 40ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj bytes = x; 41ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj} 42496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 43ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardjvoid StopBenchmarkTiming() { 44ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj if(t0 != 0) 45ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj ns += nsec() - t0; 46ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj t0 = 0; 47496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 48496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 49496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjvoid StartBenchmarkTiming() { 50496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj if(t0 == 0) 51496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj t0 = nsec(); 52496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 53496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 54496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjvoid SetBenchmarkItemsProcessed(int n) { 55496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj items = n; 56496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 57496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 58496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjvoid BenchmarkMemoryUsage() { 59496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj // TODO(rsc): Implement. 60496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 61496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 62496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjint NumCPUs() { 63496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj return 1; 64496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj} 65496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj 66496a58d130a28ac3a5ba33c9012dabbe61dc852csewardjstatic void runN(Benchmark *b, int n, int siz) { 67496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj bytes = 0; 68496a58d130a28ac3a5ba33c9012dabbe61dc852csewardj items = 0; 69c97096c44637ae5775ed305b19f16f0b505f17d8sewardj ns = 0; 70e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj t0 = nsec(); 71e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj if(b->fn) 72c9a43665879a03886b27a65b68af2a2c11b04f59sewardj b->fn(n); 73c9a43665879a03886b27a65b68af2a2c11b04f59sewardj else if(b->fnr) 74c9a43665879a03886b27a65b68af2a2c11b04f59sewardj b->fnr(n, siz); 75c9a43665879a03886b27a65b68af2a2c11b04f59sewardj else { 76c9a43665879a03886b27a65b68af2a2c11b04f59sewardj fprintf(stderr, "%s: missing function\n", b->name); 77c9a43665879a03886b27a65b68af2a2c11b04f59sewardj exit(2); 78c9a43665879a03886b27a65b68af2a2c11b04f59sewardj } 799b96767debeeb1f78378f0e7e295fe6762c64002sewardj if(t0 != 0) 80c9a43665879a03886b27a65b68af2a2c11b04f59sewardj ns += nsec() - t0; 81c9a43665879a03886b27a65b68af2a2c11b04f59sewardj} 82c9a43665879a03886b27a65b68af2a2c11b04f59sewardj 83d1725d18b61bf7912a9099686179faef5815dba1sewardjstatic int round(int n) { 84e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj int base = 1; 85e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj 8635421a3cfd43bc829d27ee15bd34bbc7cb690805sewardj while(base*10 < n) 872d3f77c12d2911173fd182d0b6e954196dee9135sewardj base *= 10; 88c97096c44637ae5775ed305b19f16f0b505f17d8sewardj if(n < 2*base) 89e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj return 2*base; 90af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj if(n < 5*base) 91af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return 5*base; 92af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj return 10*base; 93af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj} 94af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 95af1cecaf9c96f99381dda16f41d286fc3e4d220asewardjvoid RunBench(Benchmark* b, int nthread, int siz) { 96af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj int n, last; 97af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj 98af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj // TODO(rsc): Threaded benchmarks. 99af1cecaf9c96f99381dda16f41d286fc3e4d220asewardj if(nthread != 1) 100c97096c44637ae5775ed305b19f16f0b505f17d8sewardj return; 101ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj 102ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj // run once in case it's expensive 103c9a43665879a03886b27a65b68af2a2c11b04f59sewardj n = 1; 104c9a43665879a03886b27a65b68af2a2c11b04f59sewardj runN(b, n, siz); 105c9a43665879a03886b27a65b68af2a2c11b04f59sewardj while(ns < (int)1e9 && n < (int)1e9) { 106c9a43665879a03886b27a65b68af2a2c11b04f59sewardj last = n; 107c9a43665879a03886b27a65b68af2a2c11b04f59sewardj if(ns/n == 0) 108c9a43665879a03886b27a65b68af2a2c11b04f59sewardj n = 1e9; 1091e6ad745ebafd0524da1da27a4b85524fa84f777sewardj else 1101e6ad745ebafd0524da1da27a4b85524fa84f777sewardj n = 1e9 / (ns/n); 1111e6ad745ebafd0524da1da27a4b85524fa84f777sewardj 1121e6ad745ebafd0524da1da27a4b85524fa84f777sewardj n = max(last+1, min(n+n/2, 100*last)); 1131e6ad745ebafd0524da1da27a4b85524fa84f777sewardj n = round(n); 114207557ab2ea38239b670785c976b89d50bbb0eccsewardj runN(b, n, siz); 115ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj } 116ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj 117ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj char mb[100]; 118e3d0d2ea7b2161ae4f627882be33902ce5f3f8besewardj char suf[100]; 119ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj mb[0] = '\0'; 120ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj suf[0] = '\0'; 121ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj if(ns > 0 && bytes > 0) 122c97096c44637ae5775ed305b19f16f0b505f17d8sewardj snprintf(mb, sizeof mb, "\t%7.2f MB/s", ((double)bytes/1e6)/((double)ns/1e9)); 123c97096c44637ae5775ed305b19f16f0b505f17d8sewardj if(b->fnr || b->lo != b->hi) { 124c97096c44637ae5775ed305b19f16f0b505f17d8sewardj if(siz >= (1<<20)) 125c97096c44637ae5775ed305b19f16f0b505f17d8sewardj snprintf(suf, sizeof suf, "/%dM", siz/(1<<20)); 126a58ea668d4725b87a146cf43cc48b8ea6ead84casewardj else if(siz >= (1<<10)) 12717442fe8094d0f82266e5a05509f62cac8f7539esewardj snprintf(suf, sizeof suf, "/%dK", siz/(1<<10)); 1281e6ad745ebafd0524da1da27a4b85524fa84f777sewardj else 129ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj snprintf(suf, sizeof suf, "/%d", siz); 130ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj } 131ac6b7121413a24ce2f63727d50ac4f3a1b9027e6sewardj printf("%s%s\t%8lld\t%10lld ns/op%s\n", b->name, suf, (long long)n, (long long)ns/n, mb); 132ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj fflush(stdout); 133ba99931f6dfa264d7bc7c3845a46fc955ab56d93sewardj} 13417442fe8094d0f82266e5a05509f62cac8f7539esewardj 13517442fe8094d0f82266e5a05509f62cac8f7539esewardjstatic int match(const char* name, int argc, const char** argv) { 13617442fe8094d0f82266e5a05509f62cac8f7539esewardj if(argc == 1) 13717442fe8094d0f82266e5a05509f62cac8f7539esewardj return 1; 13817442fe8094d0f82266e5a05509f62cac8f7539esewardj for(int i = 1; i < argc; i++) 13917442fe8094d0f82266e5a05509f62cac8f7539esewardj if(RE2::PartialMatch(name, argv[i])) 1401e6ad745ebafd0524da1da27a4b85524fa84f777sewardj return 1; 141c97096c44637ae5775ed305b19f16f0b505f17d8sewardj return 0; 142695cff9303ef5dc8079117acfd632b44edb1f010sewardj} 143695cff9303ef5dc8079117acfd632b44edb1f010sewardj 14435421a3cfd43bc829d27ee15bd34bbc7cb690805sewardjint main(int argc, const char** argv) { 1454345f7a3ecee1dde39b3c9b58372a5af97a06e8csewardj for(int i = 0; i < nbenchmarks; i++) { 146ec6ad593611ccd69f797e3add4d23a5f31aa84d6sewardj Benchmark* b = benchmarks[i]; 147c97096c44637ae5775ed305b19f16f0b505f17d8sewardj if(match(b->name, argc, argv)) 1488ea867b06de73d909c29e243407713c291c8414esewardj for(int j = b->threadlo; j <= b->threadhi; j++) 1498ea867b06de73d909c29e243407713c291c8414esewardj for(int k = max(b->lo, 1); k <= max(b->hi, 1); k<<=1) 1508ea867b06de73d909c29e243407713c291c8414esewardj RunBench(b, j, k); 15177352545d8416a36a4e6310aaea6b0205508aea2sewardj } 1528ea867b06de73d909c29e243407713c291c8414esewardj} 1538ea867b06de73d909c29e243407713c291c8414esewardj 1548ea867b06de73d909c29e243407713c291c8414esewardj