• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2009 The RE2 Authors.  All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 #ifndef UTIL_BENCHMARK_H_
6 #define UTIL_BENCHMARK_H_
7 
8 #include <stdint.h>
9 #include <functional>
10 
11 #include "util/logging.h"
12 #include "util/util.h"
13 
14 // Globals for the old benchmark API.
15 void StartBenchmarkTiming();
16 void StopBenchmarkTiming();
17 void SetBenchmarkBytesProcessed(int64_t b);
18 void SetBenchmarkItemsProcessed(int64_t i);
19 
20 namespace benchmark {
21 
22 // The new benchmark API implemented as a layer over the old benchmark API.
23 // (Please refer to https://github.com/google/benchmark for documentation.)
24 class State {
25  private:
26   class Iterator {
27    public:
28     // Benchmark code looks like this:
29     //
30     //   for (auto _ : state) {
31     //     // ...
32     //   }
33     //
34     // We try to avoid compiler warnings about such variables being unused.
35     struct ATTRIBUTE_UNUSED Value {};
36 
Iterator(int64_t iters)37     explicit Iterator(int64_t iters) : iters_(iters) {}
38 
39     bool operator!=(const Iterator& that) const {
40       if (iters_ != that.iters_) {
41         return true;
42       } else {
43         // We are about to stop the loop, so stop timing.
44         StopBenchmarkTiming();
45         return false;
46       }
47     }
48 
49     Value operator*() const {
50       return Value();
51     }
52 
53     Iterator& operator++() {
54       --iters_;
55       return *this;
56     }
57 
58    private:
59     int64_t iters_;
60   };
61 
62  public:
State(int64_t iters)63   explicit State(int64_t iters)
64       : iters_(iters), arg_(0), has_arg_(false) {}
65 
State(int64_t iters,int64_t arg)66   State(int64_t iters, int64_t arg)
67       : iters_(iters), arg_(arg), has_arg_(true) {}
68 
begin()69   Iterator begin() {
70     // We are about to start the loop, so start timing.
71     StartBenchmarkTiming();
72     return Iterator(iters_);
73   }
74 
end()75   Iterator end() {
76     return Iterator(0);
77   }
78 
SetBytesProcessed(int64_t b)79   void SetBytesProcessed(int64_t b) { SetBenchmarkBytesProcessed(b); }
SetItemsProcessed(int64_t i)80   void SetItemsProcessed(int64_t i) { SetBenchmarkItemsProcessed(i); }
iterations()81   int64_t iterations() const { return iters_; }
82   // Pretend to support multiple arguments.
range(int pos)83   int64_t range(int pos) const { CHECK(has_arg_); return arg_; }
84 
85  private:
86   int64_t iters_;
87   int64_t arg_;
88   bool has_arg_;
89 
90   State(const State&) = delete;
91   State& operator=(const State&) = delete;
92 };
93 
94 }  // namespace benchmark
95 
96 namespace testing {
97 
98 class Benchmark {
99  public:
Benchmark(const char * name,void (* func)(benchmark::State &))100   Benchmark(const char* name, void (*func)(benchmark::State&))
101       : name_(name),
102         func_([func](int iters, int arg) {
103           benchmark::State state(iters);
104           func(state);
105         }),
106         lo_(0),
107         hi_(0),
108         has_arg_(false) {
109     Register();
110   }
111 
Benchmark(const char * name,void (* func)(benchmark::State &),int lo,int hi)112   Benchmark(const char* name, void (*func)(benchmark::State&), int lo, int hi)
113       : name_(name),
114         func_([func](int iters, int arg) {
115           benchmark::State state(iters, arg);
116           func(state);
117         }),
118         lo_(lo),
119         hi_(hi),
120         has_arg_(true) {
121     Register();
122   }
123 
124   // Pretend to support multiple threads.
ThreadRange(int lo,int hi)125   Benchmark* ThreadRange(int lo, int hi) { return this; }
126 
name()127   const char* name() const { return name_; }
func()128   const std::function<void(int, int)>& func() const { return func_; }
lo()129   int lo() const { return lo_; }
hi()130   int hi() const { return hi_; }
has_arg()131   bool has_arg() const { return has_arg_; }
132 
133  private:
134   void Register();
135 
136   const char* name_;
137   std::function<void(int, int)> func_;
138   int lo_;
139   int hi_;
140   bool has_arg_;
141 
142   Benchmark(const Benchmark&) = delete;
143   Benchmark& operator=(const Benchmark&) = delete;
144 };
145 
146 }  // namespace testing
147 
148 #define BENCHMARK(f)                     \
149   ::testing::Benchmark* _benchmark_##f = \
150       (new ::testing::Benchmark(#f, f))
151 
152 #define BENCHMARK_RANGE(f, lo, hi)       \
153   ::testing::Benchmark* _benchmark_##f = \
154       (new ::testing::Benchmark(#f, f, lo, hi))
155 
156 #endif  // UTIL_BENCHMARK_H_
157