-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathbenchmark.cc
More file actions
131 lines (112 loc) · 2.93 KB
/
Copy pathbenchmark.cc
File metadata and controls
131 lines (112 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2009 The RE2 Authors. All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <chrono>
#include "util/benchmark.h"
#include "util/flags.h"
#include "re2/re2.h"
#ifdef _WIN32
#define snprintf _snprintf
#endif
using ::testing::Benchmark;
static Benchmark* benchmarks[10000];
static int nbenchmarks;
void Benchmark::Register() {
lo_ = std::max(1, lo_);
hi_ = std::max(lo_, hi_);
benchmarks[nbenchmarks++] = this;
}
static int64_t nsec() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}
static int64_t t0;
static int64_t ns;
static int64_t bytes;
static int64_t items;
void StartBenchmarkTiming() {
if (t0 == 0) {
t0 = nsec();
}
}
void StopBenchmarkTiming() {
if (t0 != 0) {
ns += nsec() - t0;
t0 = 0;
}
}
void SetBenchmarkBytesProcessed(int64_t b) { bytes = b; }
void SetBenchmarkItemsProcessed(int64_t i) { items = i; }
static void RunFunc(Benchmark* b, int iters, int arg) {
t0 = nsec();
ns = 0;
bytes = 0;
items = 0;
b->func()(iters, arg);
StopBenchmarkTiming();
}
static int round(int n) {
int base = 1;
while (base * 10 < n) base *= 10;
if (n < 2 * base) return 2 * base;
if (n < 5 * base) return 5 * base;
return 10 * base;
}
static void RunBench(Benchmark* b, int arg) {
int iters, last;
// Run once just in case it's expensive.
iters = 1;
RunFunc(b, iters, arg);
while (ns < (int)1e9 && iters < (int)1e9) {
last = iters;
if (ns / iters == 0) {
iters = (int)1e9;
} else {
iters = (int)1e9 / static_cast<int>(ns / iters);
}
iters = std::max(last + 1, std::min(iters + iters / 2, 100 * last));
iters = round(iters);
RunFunc(b, iters, arg);
}
char mb[100];
char suf[100];
mb[0] = '\0';
suf[0] = '\0';
if (ns > 0 && bytes > 0)
snprintf(mb, sizeof mb, "\t%7.2f MB/s",
((double)bytes / 1e6) / ((double)ns / 1e9));
if (b->has_arg()) {
if (arg >= (1 << 20)) {
snprintf(suf, sizeof suf, "/%dM", arg / (1 << 20));
} else if (arg >= (1 << 10)) {
snprintf(suf, sizeof suf, "/%dK", arg / (1 << 10));
} else {
snprintf(suf, sizeof suf, "/%d", arg);
}
}
printf("%s%s\t%8d\t%10lld ns/op%s\n", b->name(), suf, iters,
(long long)ns / iters, mb);
fflush(stdout);
}
static bool WantBench(const char* name, int argc, const char** argv) {
if (argc == 1) return true;
for (int i = 1; i < argc; i++) {
if (RE2::PartialMatch(name, argv[i]))
return true;
}
return false;
}
int main(int argc, const char** argv) {
for (int i = 0; i < nbenchmarks; i++) {
Benchmark* b = benchmarks[i];
if (!WantBench(b->name(), argc, argv))
continue;
for (int arg = b->lo(); arg <= b->hi(); arg <<= 1)
RunBench(b, arg);
}
}