diff options
Diffstat (limited to 'libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h')
-rw-r--r-- | libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h | 167 |
1 files changed, 114 insertions, 53 deletions
diff --git a/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h b/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h index 664ca2a9083..1a481ac48d7 100644 --- a/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h +++ b/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h @@ -38,12 +38,12 @@ int main(int argc, char** argv) { // of memcpy() calls of different lengths: static void BM_memcpy(benchmark::State& state) { - char* src = new char[state.range_x()]; char* dst = new char[state.range_x()]; - memset(src, 'x', state.range_x()); + char* src = new char[state.range(0)]; char* dst = new char[state.range(0)]; + memset(src, 'x', state.range(0)); while (state.KeepRunning()) - memcpy(dst, src, state.range_x()); + memcpy(dst, src, state.range(0)); state.SetBytesProcessed(int64_t(state.iterations()) * - int64_t(state.range_x())); + int64_t(state.range(0))); delete[] src; delete[] dst; } BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); @@ -60,27 +60,27 @@ BENCHMARK(BM_memcpy)->Range(8, 8<<10); static void BM_SetInsert(benchmark::State& state) { while (state.KeepRunning()) { state.PauseTiming(); - set<int> data = ConstructRandomSet(state.range_x()); + set<int> data = ConstructRandomSet(state.range(0)); state.ResumeTiming(); - for (int j = 0; j < state.range_y(); ++j) + for (int j = 0; j < state.range(1); ++j) data.insert(RandomNumber()); } } BENCHMARK(BM_SetInsert) - ->ArgPair(1<<10, 1) - ->ArgPair(1<<10, 8) - ->ArgPair(1<<10, 64) - ->ArgPair(1<<10, 512) - ->ArgPair(8<<10, 1) - ->ArgPair(8<<10, 8) - ->ArgPair(8<<10, 64) - ->ArgPair(8<<10, 512); + ->Args({1<<10, 1}) + ->Args({1<<10, 8}) + ->Args({1<<10, 64}) + ->Args({1<<10, 512}) + ->Args({8<<10, 1}) + ->Args({8<<10, 8}) + ->Args({8<<10, 64}) + ->Args({8<<10, 512}); // The preceding code is quite repetitive, and can be replaced with // the following short-hand. The following macro will pick a few // appropriate arguments in the product of the two specified ranges // and will generate a microbenchmark for each such pair. -BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512); +BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); // For more complex patterns of inputs, passing a custom function // to Apply allows programmatic specification of an @@ -90,7 +90,7 @@ BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 512); static void CustomArguments(benchmark::internal::Benchmark* b) { for (int i = 0; i <= 10; ++i) for (int j = 32; j <= 1024*1024; j *= 8) - b->ArgPair(i, j); + b->Args({i, j}); } BENCHMARK(BM_SetInsert)->Apply(CustomArguments); @@ -101,14 +101,14 @@ template <class Q> int BM_Sequential(benchmark::State& state) { Q q; typename Q::value_type v; while (state.KeepRunning()) { - for (int i = state.range_x(); i--; ) + for (int i = state.range(0); i--; ) q.push(v); - for (int e = state.range_x(); e--; ) + for (int e = state.range(0); e--; ) q.Wait(&v); } // actually messages, not bytes: state.SetBytesProcessed( - static_cast<int64_t>(state.iterations())*state.range_x()); + static_cast<int64_t>(state.iterations())*state.range(0)); } BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10); @@ -153,8 +153,15 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); #include <stddef.h> #include <stdint.h> +#include <vector> + #include "macros.h" +#if defined(BENCHMARK_HAS_CXX11) +#include <type_traits> +#include <utility> +#endif + namespace benchmark { class BenchmarkReporter; @@ -165,11 +172,16 @@ void Initialize(int* argc, char** argv); // of each matching benchmark. Otherwise run each matching benchmark and // report the results. // -// The second overload reports the results using the specified 'reporter'. +// The second and third overload use the specified 'console_reporter' and +// 'file_reporter' respectively. 'file_reporter' will write to the file specified +// by '--benchmark_output'. If '--benchmark_output' is not given the +// 'file_reporter' is ignored. // // RETURNS: The number of matching benchmarks. size_t RunSpecifiedBenchmarks(); -size_t RunSpecifiedBenchmarks(BenchmarkReporter* reporter); +size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter); +size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter, + BenchmarkReporter* file_reporter); // If this routine is called, peak memory allocation past this point in the @@ -258,7 +270,7 @@ typedef double(BigOFunc)(int); // benchmark to use. class State { public: - State(size_t max_iters, bool has_x, int x, bool has_y, int y, + State(size_t max_iters, const std::vector<int>& ranges, int thread_i, int n_threads); // Returns true if the benchmark should continue through another iteration. @@ -367,7 +379,7 @@ public: } BENCHMARK_ALWAYS_INLINE - size_t complexity_length_n() { + int complexity_length_n() { return complexity_n_; } @@ -413,17 +425,9 @@ public: // Range arguments for this run. CHECKs if the argument has been set. BENCHMARK_ALWAYS_INLINE - int range_x() const { - assert(has_range_x_); - ((void)has_range_x_); // Prevent unused warning. - return range_x_; - } - - BENCHMARK_ALWAYS_INLINE - int range_y() const { - assert(has_range_y_); - ((void)has_range_y_); // Prevent unused warning. - return range_y_; + int range(std::size_t pos) const { + assert(range_.size() > pos); + return range_[pos]; } BENCHMARK_ALWAYS_INLINE @@ -434,11 +438,7 @@ private: bool finished_; size_t total_iterations_; - bool has_range_x_; - int range_x_; - - bool has_range_y_; - int range_y_; + std::vector<int> range_; size_t bytes_processed_; size_t items_processed_; @@ -489,24 +489,22 @@ public: // REQUIRES: The function passed to the constructor must accept an arg1. Benchmark* Range(int start, int limit); - // Run this benchmark once for every value in the range [start..limit] + // Run this benchmark once for all values in the range [start..limit] with specific step // REQUIRES: The function passed to the constructor must accept an arg1. - Benchmark* DenseRange(int start, int limit); + Benchmark* DenseRange(int start, int limit, int step = 1); - // Run this benchmark once with "x,y" as the extra arguments passed + // Run this benchmark once with "args" as the extra arguments passed // to the function. - // REQUIRES: The function passed to the constructor must accept arg1,arg2. - Benchmark* ArgPair(int x, int y); + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Args(const std::vector<int>& args); - // Pick a set of values A from the range [lo1..hi1] and a set - // of values B from the range [lo2..hi2]. Run the benchmark for - // every pair of values in the cartesian product of A and B - // (i.e., for all combinations of the values in A and B). - // REQUIRES: The function passed to the constructor must accept arg1,arg2. - Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2); + // Run this benchmark once for a number of values picked from the + // ranges [start..limit]. (starts and limits are always picked.) + // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... + Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges); // Pass this benchmark object to *func, which can customize - // the benchmark by calling various methods like Arg, ArgPair, + // the benchmark by calling various methods like Arg, Args, // Threads, etc. Benchmark* Apply(void (*func)(Benchmark* benchmark)); @@ -587,6 +585,20 @@ private: Benchmark& operator=(Benchmark const&); }; +} // namespace internal + +// Create and register a benchmark with the specified 'name' that invokes +// the specified functor 'fn'. +// +// RETURNS: A pointer to the registered benchmark. +internal::Benchmark* RegisterBenchmark(const char* name, internal::Function* fn); + +#if defined(BENCHMARK_HAS_CXX11) +template <class Lambda> +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn); +#endif + +namespace internal { // The class used to hold all Benchmarks created from static function. // (ie those created using the BENCHMARK(...) macros. class FunctionBenchmark : public Benchmark { @@ -600,8 +612,57 @@ private: Function* func_; }; +#ifdef BENCHMARK_HAS_CXX11 +template <class Lambda> +class LambdaBenchmark : public Benchmark { +public: + virtual void Run(State& st) { lambda_(st); } + +private: + template <class OLambda> + LambdaBenchmark(const char* name, OLambda&& lam) + : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {} + + LambdaBenchmark(LambdaBenchmark const&) = delete; + +private: + template <class Lam> + friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&); + + Lambda lambda_; +}; +#endif + } // end namespace internal +inline internal::Benchmark* +RegisterBenchmark(const char* name, internal::Function* fn) { + return internal::RegisterBenchmarkInternal( + ::new internal::FunctionBenchmark(name, fn)); +} + +#ifdef BENCHMARK_HAS_CXX11 +template <class Lambda> +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) { + using BenchType = internal::LambdaBenchmark<typename std::decay<Lambda>::type>; + return internal::RegisterBenchmarkInternal( + ::new BenchType(name, std::forward<Lambda>(fn))); +} +#endif + +#if defined(BENCHMARK_HAS_CXX11) && \ + (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) +template <class Lambda, class ...Args> +internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn, + Args&&... args) { + return benchmark::RegisterBenchmark(name, + [=](benchmark::State& st) { fn(st, args...); }); +} +#else +#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK +#endif + + // The base class for all fixture tests. class Fixture: public internal::Benchmark { public: @@ -652,11 +713,11 @@ protected: // Old-style macros #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) -#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->ArgPair((a1), (a2)) +#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) #define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) #define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) #define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ - BENCHMARK(n)->RangePair((l1), (h1), (l2), (h2)) + BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) #if __cplusplus >= 201103L |