From cded70a1660e81f854b5d41795a514ec0825c32a Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Thu, 24 Mar 2016 22:18:55 +0100 Subject: [PATCH 1/8] Add optional ms time unit for console reporter Some benchmarks may run a few milliseconds which makes it kind of hard to visually compare, since the currently only available nanoseconds numbers can get very large in this case. Therefore this commit adds an optional command line flag --benchmark_time_unit which lets the user choose between ns and ms time units for displaying the mean execution time. --- include/benchmark/reporter.h | 3 +++ src/benchmark.cc | 19 +++++++++++++++++-- src/console_reporter.cc | 9 +++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/benchmark/reporter.h b/include/benchmark/reporter.h index d23ab657..f2a8dc25 100644 --- a/include/benchmark/reporter.h +++ b/include/benchmark/reporter.h @@ -36,6 +36,8 @@ class BenchmarkReporter { // The number of chars in the longest benchmark name. size_t name_field_width; + // The time unit for displayed execution time. + std::string time_unit; }; struct Run { @@ -94,6 +96,7 @@ protected: virtual void PrintRunData(const Run& report); size_t name_field_width_; + std::string time_unit_; }; class JSONReporter : public BenchmarkReporter { diff --git a/src/benchmark.cc b/src/benchmark.cc index 08b180e3..dd372021 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -64,6 +64,10 @@ DEFINE_int32(benchmark_repetitions, 1, "The number of runs of each benchmark. If greater than 1, the " "mean and standard deviation of the runs will be reported."); +DEFINE_string(benchmark_time_unit, "ns", + "The time unit to use for console output. Valid values are " + "'ns', or 'ms'."); + DEFINE_string(benchmark_format, "tabular", "The format to use for console output. Valid values are " "'tabular', 'json', or 'csv'."); @@ -779,7 +783,7 @@ void PrintBenchmarkList() { } } -void RunMatchingBenchmarks(const std::string& spec, +void RunMatchingBenchmarks(const std::string& spec, const std::string& timeUnit, BenchmarkReporter* reporter) { CHECK(reporter != nullptr); if (spec.empty()) return; @@ -804,6 +808,7 @@ void RunMatchingBenchmarks(const std::string& spec, context.cpu_scaling_enabled = CpuScalingEnabled(); context.name_field_width = name_field_width; + context.time_unit = timeUnit; if (reporter->ReportContext(context)) { for (const auto& benchmark : benchmarks) { @@ -838,6 +843,7 @@ void RunSpecifiedBenchmarks(BenchmarkReporter* reporter) { internal::PrintBenchmarkList(); return; } + std::string timeUnit = FLAGS_benchmark_time_unit; std::string spec = FLAGS_benchmark_filter; if (spec.empty() || spec == "all") spec = "."; // Regexp that matches all benchmarks @@ -847,7 +853,7 @@ void RunSpecifiedBenchmarks(BenchmarkReporter* reporter) { default_reporter = internal::GetDefaultReporter(); reporter = default_reporter.get(); } - internal::RunMatchingBenchmarks(spec, reporter); + internal::RunMatchingBenchmarks(spec, timeUnit, reporter); reporter->Finalize(); } @@ -860,6 +866,7 @@ void PrintUsageAndExit() { " [--benchmark_filter=]\n" " [--benchmark_min_time=]\n" " [--benchmark_repetitions=]\n" + " [--benchmark_time_unit=]\n" " [--benchmark_format=]\n" " [--color_print={true|false}]\n" " [--v=]\n"); @@ -878,6 +885,8 @@ void ParseCommandLineFlags(int* argc, char** argv) { &FLAGS_benchmark_min_time) || ParseInt32Flag(argv[i], "benchmark_repetitions", &FLAGS_benchmark_repetitions) || + ParseStringFlag(argv[i], "benchmark_time_unit", + &FLAGS_benchmark_time_unit) || ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) || ParseBoolFlag(argv[i], "color_print", @@ -891,6 +900,12 @@ void ParseCommandLineFlags(int* argc, char** argv) { PrintUsageAndExit(); } } + + if (FLAGS_benchmark_time_unit != "ns" && + FLAGS_benchmark_time_unit != "ms") { + PrintUsageAndExit(); + } + if (FLAGS_benchmark_format != "tabular" && FLAGS_benchmark_format != "json" && FLAGS_benchmark_format != "csv") { diff --git a/src/console_reporter.cc b/src/console_reporter.cc index 092936d5..6af51571 100644 --- a/src/console_reporter.cc +++ b/src/console_reporter.cc @@ -29,6 +29,7 @@ namespace benchmark { bool ConsoleReporter::ReportContext(const Context& context) { name_field_width_ = context.name_field_width; + time_unit_ = context.time_unit; std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n"; @@ -46,9 +47,11 @@ bool ConsoleReporter::ReportContext(const Context& context) { "affected.\n"; #endif + std::string timeLabel = "Time(" + time_unit_ + ")"; + std::string cpuLabel = "CPU(" + time_unit_ + ")"; int output_width = fprintf(stdout, "%-*s %10s %10s %10s\n", static_cast(name_field_width_), "Benchmark", - "Time(ns)", "CPU(ns)", "Iterations"); + timeLabel.c_str(), cpuLabel.c_str(), "Iterations"); std::cout << std::string(output_width - 1, '-') << "\n"; return true; @@ -92,7 +95,9 @@ void ConsoleReporter::PrintRunData(const Run& result) { " items/s"); } - double const multiplier = 1e9; // nano second multiplier + double const multiplier = time_unit_ == "ns" ? 1e9 : 1e3; // nano second or + // millis multiplier + ColorPrintf(COLOR_GREEN, "%-*s ", name_field_width_, result.benchmark_name.c_str()); if (result.iterations == 0) { From 3a02c462c795fd60e2620fc78c6f8c5b63aa1764 Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Thu, 24 Mar 2016 22:34:23 +0100 Subject: [PATCH 2/8] Add myself to the contributors list --- CONTRIBUTORS | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index ed55bcf2..2bbe19e0 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -32,6 +32,7 @@ Evgeny Safronov Felix Homann JianXiong Zhou Kaito Udagawa +Kai Wolf Lei Xu Matt Clarkson Oleksandr Sochka From 7c69b36078b5773fbd6b09b539a30400138607a7 Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Fri, 25 Mar 2016 22:47:27 +0100 Subject: [PATCH 3/8] Add an additional parameter for time units --- include/benchmark/benchmark_api.h | 11 +++++++++ include/benchmark/reporter.h | 13 +++++++---- src/benchmark.cc | 34 ++++++++++++++-------------- src/console_reporter.cc | 37 ++++++++++++++++++++++--------- test/CMakeLists.txt | 3 +++ test/options_test.cc | 11 +++++++++ 6 files changed, 77 insertions(+), 32 deletions(-) diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h index 7a42025a..251fd59d 100644 --- a/include/benchmark/benchmark_api.h +++ b/include/benchmark/benchmark_api.h @@ -216,6 +216,13 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { } #endif +// TimeUnit is passed to a benchmark in order to specify the order of magnitude +// for the measured time. +enum TimeUnit { + kNanosecond, + kMicrosecond, + kMillisecond +}; // State is passed to a running Benchmark and contains state for the // benchmark to use. @@ -390,6 +397,9 @@ public: // REQUIRES: The function passed to the constructor must accept an arg1. Benchmark* Arg(int x); + // Run this benchmark with the given time unit for the generated output report + Benchmark* Unit(TimeUnit unit); + // Run this benchmark once for a number of values picked from the // range [start..limit]. (start and limit are always picked.) // REQUIRES: The function passed to the constructor must accept an arg1. @@ -534,6 +544,7 @@ 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_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)) diff --git a/include/benchmark/reporter.h b/include/benchmark/reporter.h index f2a8dc25..9c4a69d3 100644 --- a/include/benchmark/reporter.h +++ b/include/benchmark/reporter.h @@ -36,13 +36,12 @@ class BenchmarkReporter { // The number of chars in the longest benchmark name. size_t name_field_width; - // The time unit for displayed execution time. - std::string time_unit; }; struct Run { Run() : iterations(1), + time_unit(kNanosecond), real_accumulated_time(0), cpu_accumulated_time(0), bytes_per_second(0), @@ -52,6 +51,7 @@ class BenchmarkReporter { std::string benchmark_name; std::string report_label; // Empty if not set by benchmark. int64_t iterations; + TimeUnit time_unit; double real_accumulated_time; double cpu_accumulated_time; @@ -86,17 +86,22 @@ protected: static void ComputeStats(std::vector const& reports, Run* mean, Run* stddev); }; +typedef std::pair TimeUnitMultiplier; + // Simple reporter that outputs benchmark data to the console. This is the // default reporter used by RunSpecifiedBenchmarks(). class ConsoleReporter : public BenchmarkReporter { public: virtual bool ReportContext(const Context& context); virtual void ReportRuns(const std::vector& reports); -protected: + + protected: virtual void PrintRunData(const Run& report); + private: + TimeUnitMultiplier getTimeUnitAndMultiplier(TimeUnit unit); + size_t name_field_width_; - std::string time_unit_; }; class JSONReporter : public BenchmarkReporter { diff --git a/src/benchmark.cc b/src/benchmark.cc index dd372021..cb55f969 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -64,10 +64,6 @@ DEFINE_int32(benchmark_repetitions, 1, "The number of runs of each benchmark. If greater than 1, the " "mean and standard deviation of the runs will be reported."); -DEFINE_string(benchmark_time_unit, "ns", - "The time unit to use for console output. Valid values are " - "'ns', or 'ms'."); - DEFINE_string(benchmark_format, "tabular", "The format to use for console output. Valid values are " "'tabular', 'json', or 'csv'."); @@ -265,6 +261,7 @@ struct Benchmark::Instance { int arg1; bool has_arg2; int arg2; + TimeUnit time_unit; bool use_real_time; double min_time; int threads; // Number of concurrent threads to use @@ -298,6 +295,7 @@ public: ~BenchmarkImp(); void Arg(int x); + void Unit(TimeUnit unit); void Range(int start, int limit); void DenseRange(int start, int limit); void ArgPair(int start, int limit); @@ -317,6 +315,7 @@ private: std::string name_; int arg_count_; std::vector< std::pair > args_; // Args for all benchmark runs + TimeUnit time_unit_; double min_time_; bool use_real_time_; std::vector thread_counts_; @@ -376,6 +375,7 @@ bool BenchmarkFamilies::FindBenchmarks( instance.arg1 = args.first; instance.has_arg2 = family->arg_count_ == 2; instance.arg2 = args.second; + instance.time_unit = family->time_unit_; instance.min_time = family->min_time_; instance.use_real_time = family->use_real_time_; instance.threads = num_threads; @@ -410,7 +410,7 @@ bool BenchmarkFamilies::FindBenchmarks( } BenchmarkImp::BenchmarkImp(const char* name) - : name_(name), arg_count_(-1), + : name_(name), arg_count_(-1), time_unit_(kNanosecond), min_time_(0.0), use_real_time_(false) { } @@ -423,6 +423,10 @@ void BenchmarkImp::Arg(int x) { args_.emplace_back(x, -1); } +void BenchmarkImp::Unit(TimeUnit unit) { + time_unit_ = unit; +} + void BenchmarkImp::Range(int start, int limit) { CHECK(arg_count_ == -1 || arg_count_ == 1); arg_count_ = 1; @@ -535,6 +539,11 @@ Benchmark* Benchmark::Arg(int x) { return this; } +Benchmark* Benchmark::Unit(TimeUnit unit) { + imp_->Unit(unit); + return this; +} + Benchmark* Benchmark::Range(int start, int limit) { imp_->Range(start, limit); return this; @@ -703,6 +712,7 @@ void RunBenchmark(const benchmark::internal::Benchmark::Instance& b, report.report_label = label; // Report the total iterations across all threads. report.iterations = static_cast(iters) * b.threads; + report.time_unit = b.time_unit; report.real_accumulated_time = real_accumulated_time; report.cpu_accumulated_time = cpu_accumulated_time; report.bytes_per_second = bytes_per_second; @@ -783,7 +793,7 @@ void PrintBenchmarkList() { } } -void RunMatchingBenchmarks(const std::string& spec, const std::string& timeUnit, +void RunMatchingBenchmarks(const std::string& spec, BenchmarkReporter* reporter) { CHECK(reporter != nullptr); if (spec.empty()) return; @@ -808,7 +818,6 @@ void RunMatchingBenchmarks(const std::string& spec, const std::string& timeUnit, context.cpu_scaling_enabled = CpuScalingEnabled(); context.name_field_width = name_field_width; - context.time_unit = timeUnit; if (reporter->ReportContext(context)) { for (const auto& benchmark : benchmarks) { @@ -843,7 +852,6 @@ void RunSpecifiedBenchmarks(BenchmarkReporter* reporter) { internal::PrintBenchmarkList(); return; } - std::string timeUnit = FLAGS_benchmark_time_unit; std::string spec = FLAGS_benchmark_filter; if (spec.empty() || spec == "all") spec = "."; // Regexp that matches all benchmarks @@ -853,7 +861,7 @@ void RunSpecifiedBenchmarks(BenchmarkReporter* reporter) { default_reporter = internal::GetDefaultReporter(); reporter = default_reporter.get(); } - internal::RunMatchingBenchmarks(spec, timeUnit, reporter); + internal::RunMatchingBenchmarks(spec, reporter); reporter->Finalize(); } @@ -866,7 +874,6 @@ void PrintUsageAndExit() { " [--benchmark_filter=]\n" " [--benchmark_min_time=]\n" " [--benchmark_repetitions=]\n" - " [--benchmark_time_unit=]\n" " [--benchmark_format=]\n" " [--color_print={true|false}]\n" " [--v=]\n"); @@ -885,8 +892,6 @@ void ParseCommandLineFlags(int* argc, char** argv) { &FLAGS_benchmark_min_time) || ParseInt32Flag(argv[i], "benchmark_repetitions", &FLAGS_benchmark_repetitions) || - ParseStringFlag(argv[i], "benchmark_time_unit", - &FLAGS_benchmark_time_unit) || ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) || ParseBoolFlag(argv[i], "color_print", @@ -901,11 +906,6 @@ void ParseCommandLineFlags(int* argc, char** argv) { } } - if (FLAGS_benchmark_time_unit != "ns" && - FLAGS_benchmark_time_unit != "ms") { - PrintUsageAndExit(); - } - if (FLAGS_benchmark_format != "tabular" && FLAGS_benchmark_format != "json" && FLAGS_benchmark_format != "csv") { diff --git a/src/console_reporter.cc b/src/console_reporter.cc index 6af51571..c07ed5ae 100644 --- a/src/console_reporter.cc +++ b/src/console_reporter.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "check.h" @@ -29,7 +30,6 @@ namespace benchmark { bool ConsoleReporter::ReportContext(const Context& context) { name_field_width_ = context.name_field_width; - time_unit_ = context.time_unit; std::cerr << "Run on (" << context.num_cpus << " X " << context.mhz_per_cpu << " MHz CPU " << ((context.num_cpus > 1) ? "s" : "") << ")\n"; @@ -47,11 +47,9 @@ bool ConsoleReporter::ReportContext(const Context& context) { "affected.\n"; #endif - std::string timeLabel = "Time(" + time_unit_ + ")"; - std::string cpuLabel = "CPU(" + time_unit_ + ")"; - int output_width = fprintf(stdout, "%-*s %10s %10s %10s\n", + int output_width = fprintf(stdout, "%-*s %13s %13s %10s\n", static_cast(name_field_width_), "Benchmark", - timeLabel.c_str(), cpuLabel.c_str(), "Iterations"); + "Time", "CPU", "Iterations"); std::cout << std::string(output_width - 1, '-') << "\n"; return true; @@ -95,21 +93,26 @@ void ConsoleReporter::PrintRunData(const Run& result) { " items/s"); } - double const multiplier = time_unit_ == "ns" ? 1e9 : 1e3; // nano second or - // millis multiplier + double multiplier; + const char* timeLabel; + std::tie(timeLabel, multiplier) = getTimeUnitAndMultiplier(result.time_unit); ColorPrintf(COLOR_GREEN, "%-*s ", name_field_width_, result.benchmark_name.c_str()); if (result.iterations == 0) { - ColorPrintf(COLOR_YELLOW, "%10.0f %10.0f ", + ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ", result.real_accumulated_time * multiplier, - result.cpu_accumulated_time * multiplier); + timeLabel, + result.cpu_accumulated_time * multiplier, + timeLabel); } else { - ColorPrintf(COLOR_YELLOW, "%10.0f %10.0f ", + ColorPrintf(COLOR_YELLOW, "%10.0f %s %10.0f %s ", (result.real_accumulated_time * multiplier) / (static_cast(result.iterations)), + timeLabel, (result.cpu_accumulated_time * multiplier) / - (static_cast(result.iterations))); + (static_cast(result.iterations)), + timeLabel); } ColorPrintf(COLOR_CYAN, "%10lld", result.iterations); ColorPrintf(COLOR_DEFAULT, "%*s %*s %s\n", @@ -118,4 +121,16 @@ void ConsoleReporter::PrintRunData(const Run& result) { result.report_label.c_str()); } +TimeUnitMultiplier ConsoleReporter::getTimeUnitAndMultiplier(TimeUnit unit) { + switch (unit) { + case kMillisecond: + return std::make_pair("ms", 1e3); + case kMicrosecond: + return std::make_pair("us", 1e6); + case kNanosecond: + default: + return std::make_pair("ns", 1e9); + } +} + } // end namespace benchmark diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a10a53a9..196c0edf 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,8 @@ # Enable the tests +# Allow the source files to find headers in src/ +include_directories(${PROJECT_SOURCE_DIR}/src) + find_package(Threads REQUIRED) set(CXX03_FLAGS "${CMAKE_CXX_FLAGS}") diff --git a/test/options_test.cc b/test/options_test.cc index d4c682d4..47563fa5 100644 --- a/test/options_test.cc +++ b/test/options_test.cc @@ -1,11 +1,22 @@ #include "benchmark/benchmark_api.h" +#include "sleep.h" void BM_basic(benchmark::State& state) { while (state.KeepRunning()) { } } + +void BM_basic_slow(benchmark::State& state) { + while (state.KeepRunning()) { + benchmark::SleepForMilliseconds(state.range_x()); + } +} + BENCHMARK(BM_basic); BENCHMARK(BM_basic)->Arg(42); +BENCHMARK(BM_basic_slow)->Arg(10)->Unit(benchmark::kNanosecond); +BENCHMARK(BM_basic_slow)->Arg(100)->Unit(benchmark::kMicrosecond); +BENCHMARK(BM_basic_slow)->Arg(1000)->Unit(benchmark::kMillisecond); BENCHMARK(BM_basic)->Range(1, 8); BENCHMARK(BM_basic)->DenseRange(10, 15); BENCHMARK(BM_basic)->ArgPair(42, 42); From 0b4111c3b31db8806e0c3960c7f1f541b20cdb8b Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Mon, 28 Mar 2016 21:32:11 +0200 Subject: [PATCH 4/8] Refactor GetTimeUnitAndMultiplier and add example --- README.md | 8 ++++++++ include/benchmark/benchmark_api.h | 7 +++++++ include/benchmark/reporter.h | 10 ++++------ src/console_reporter.cc | 14 +------------- src/reporter.cc | 12 ++++++++++++ 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 21ae478b..b4c6f7c2 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,14 @@ static void BM_test(benchmark::State& state) { } ``` +If a benchmark runs a few milliseconds it may be hard to visually compare the +measured times, since the output data is given in nanoseconds per default. In +order to manually set the time unit, you can specify it manually: + +```c++ +BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); +``` + Benchmark Fixtures ------------------ Fixture tests are created by diff --git a/include/benchmark/benchmark_api.h b/include/benchmark/benchmark_api.h index 251fd59d..f7440151 100644 --- a/include/benchmark/benchmark_api.h +++ b/include/benchmark/benchmark_api.h @@ -137,6 +137,13 @@ static void BM_MultiThreaded(benchmark::State& state) { } } BENCHMARK(BM_MultiThreaded)->Threads(4); + + +If a benchmark runs a few milliseconds it may be hard to visually compare the +measured times, since the output data is given in nanoseconds per default. In +order to manually set the time unit, you can specify it manually: + +BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); */ #ifndef BENCHMARK_BENCHMARK_API_H_ diff --git a/include/benchmark/reporter.h b/include/benchmark/reporter.h index 9c4a69d3..aaf5fbff 100644 --- a/include/benchmark/reporter.h +++ b/include/benchmark/reporter.h @@ -22,6 +22,8 @@ namespace benchmark { +typedef std::pair TimeUnitMultiplier; + // Interface for custom benchmark result printers. // By default, benchmark reports are printed to stdout. However an application // can control the destination of the reports by calling @@ -83,11 +85,10 @@ class BenchmarkReporter { virtual ~BenchmarkReporter(); protected: - static void ComputeStats(std::vector const& reports, Run* mean, Run* stddev); + static void ComputeStats(std::vector const& reports, Run* mean, Run* stddev); + static TimeUnitMultiplier GetTimeUnitAndMultiplier(TimeUnit unit); }; -typedef std::pair TimeUnitMultiplier; - // Simple reporter that outputs benchmark data to the console. This is the // default reporter used by RunSpecifiedBenchmarks(). class ConsoleReporter : public BenchmarkReporter { @@ -98,9 +99,6 @@ class ConsoleReporter : public BenchmarkReporter { protected: virtual void PrintRunData(const Run& report); - private: - TimeUnitMultiplier getTimeUnitAndMultiplier(TimeUnit unit); - size_t name_field_width_; }; diff --git a/src/console_reporter.cc b/src/console_reporter.cc index c07ed5ae..375e8610 100644 --- a/src/console_reporter.cc +++ b/src/console_reporter.cc @@ -95,7 +95,7 @@ void ConsoleReporter::PrintRunData(const Run& result) { double multiplier; const char* timeLabel; - std::tie(timeLabel, multiplier) = getTimeUnitAndMultiplier(result.time_unit); + std::tie(timeLabel, multiplier) = GetTimeUnitAndMultiplier(result.time_unit); ColorPrintf(COLOR_GREEN, "%-*s ", name_field_width_, result.benchmark_name.c_str()); @@ -121,16 +121,4 @@ void ConsoleReporter::PrintRunData(const Run& result) { result.report_label.c_str()); } -TimeUnitMultiplier ConsoleReporter::getTimeUnitAndMultiplier(TimeUnit unit) { - switch (unit) { - case kMillisecond: - return std::make_pair("ms", 1e3); - case kMicrosecond: - return std::make_pair("us", 1e6); - case kNanosecond: - default: - return std::make_pair("ns", 1e9); - } -} - } // end namespace benchmark diff --git a/src/reporter.cc b/src/reporter.cc index 4b47e3d5..036546e7 100644 --- a/src/reporter.cc +++ b/src/reporter.cc @@ -77,6 +77,18 @@ void BenchmarkReporter::ComputeStats( stddev_data->items_per_second = items_per_second_stat.StdDev(); } +TimeUnitMultiplier BenchmarkReporter::GetTimeUnitAndMultiplier(TimeUnit unit) { + switch (unit) { + case kMillisecond: + return std::make_pair("ms", 1e3); + case kMicrosecond: + return std::make_pair("us", 1e6); + case kNanosecond: + default: + return std::make_pair("ns", 1e9); + } +} + void BenchmarkReporter::Finalize() { } From e6d62fd135d7c1c621ff3b25056bd5ea4d1754ec Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Tue, 29 Mar 2016 20:35:38 +0200 Subject: [PATCH 5/8] Add GetTimeAndMultiplier to json and csv reporter as well --- src/csv_reporter.cc | 8 ++++++-- src/json_reporter.cc | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/csv_reporter.cc b/src/csv_reporter.cc index d78a9dfb..3284ba8b 100644 --- a/src/csv_reporter.cc +++ b/src/csv_reporter.cc @@ -42,7 +42,7 @@ bool CSVReporter::ReportContext(const Context& context) { std::cerr << "***WARNING*** Library was built as DEBUG. Timings may be " "affected.\n"; #endif - std::cout << "name,iterations,real_time,cpu_time,bytes_per_second," + std::cout << "name,iterations,real_time,cpu_time,time_unit,bytes_per_second," "items_per_second,label\n"; return true; } @@ -66,7 +66,10 @@ void CSVReporter::ReportRuns(std::vector const& reports) { } void CSVReporter::PrintRunData(Run const& run) { - double const multiplier = 1e9; // nano second multiplier + double multiplier; + const char* timeLabel; + std::tie(timeLabel, multiplier) = GetTimeUnitAndMultiplier(run.time_unit); + double cpu_time = run.cpu_accumulated_time * multiplier; double real_time = run.real_accumulated_time * multiplier; if (run.iterations != 0) { @@ -83,6 +86,7 @@ void CSVReporter::PrintRunData(Run const& run) { std::cout << run.iterations << ","; std::cout << real_time << ","; std::cout << cpu_time << ","; + std::cout << timeLabel << ","; if (run.bytes_per_second > 0.0) { std::cout << run.bytes_per_second; diff --git a/src/json_reporter.cc b/src/json_reporter.cc index def50ac4..b0198fb6 100644 --- a/src/json_reporter.cc +++ b/src/json_reporter.cc @@ -120,7 +120,10 @@ void JSONReporter::Finalize() { } void JSONReporter::PrintRunData(Run const& run) { - double const multiplier = 1e9; // nano second multiplier + double multiplier; + const char* timeLabel; + std::tie(timeLabel, multiplier) = GetTimeUnitAndMultiplier(run.time_unit); + double cpu_time = run.cpu_accumulated_time * multiplier; double real_time = run.real_accumulated_time * multiplier; if (run.iterations != 0) { @@ -140,7 +143,10 @@ void JSONReporter::PrintRunData(Run const& run) { << FormatKV("real_time", RoundDouble(real_time)) << ",\n"; out << indent - << FormatKV("cpu_time", RoundDouble(cpu_time)); + << FormatKV("cpu_time", RoundDouble(cpu_time)) + << ",\n"; + out << indent + << FormatKV("time_unit", timeLabel); if (run.bytes_per_second > 0.0) { out << ",\n" << indent << FormatKV("bytes_per_second", RoundDouble(run.bytes_per_second)); From 1043f45bedb5afcd982f4a4b4be716bcabb286f4 Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Tue, 29 Mar 2016 22:10:07 +0200 Subject: [PATCH 6/8] Add explanatory comment why src headers are needed in test/CMakeLists.txt --- test/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 196c0edf..31d62e8f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,7 @@ # Enable the tests -# Allow the source files to find headers in src/ +# Allow the test files to find headers in src/ since we rely on +# SleepForMilliseconds(int milliseconds) in options_test.cc include_directories(${PROJECT_SOURCE_DIR}/src) find_package(Threads REQUIRED) From 1203b3cbe47ad772291fe520efb2a029687229ed Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Wed, 30 Mar 2016 09:14:04 +0200 Subject: [PATCH 7/8] Fix missing header in csv/json_reporter --- src/csv_reporter.cc | 1 + src/json_reporter.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/src/csv_reporter.cc b/src/csv_reporter.cc index 3284ba8b..3f67d1de 100644 --- a/src/csv_reporter.cc +++ b/src/csv_reporter.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "string_util.h" diff --git a/src/json_reporter.cc b/src/json_reporter.cc index b0198fb6..7ed141fc 100644 --- a/src/json_reporter.cc +++ b/src/json_reporter.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "string_util.h" From fb733897c5eea5b9a04ebed5cfae37d608262129 Mon Sep 17 00:00:00 2001 From: Kai Wolf Date: Mon, 2 May 2016 19:53:45 +0200 Subject: [PATCH 8/8] Remove sleep.h dependency for tests --- test/CMakeLists.txt | 4 ---- test/options_test.cc | 12 ++++++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 31d62e8f..a10a53a9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,9 +1,5 @@ # Enable the tests -# Allow the test files to find headers in src/ since we rely on -# SleepForMilliseconds(int milliseconds) in options_test.cc -include_directories(${PROJECT_SOURCE_DIR}/src) - find_package(Threads REQUIRED) set(CXX03_FLAGS "${CMAKE_CXX_FLAGS}") diff --git a/test/options_test.cc b/test/options_test.cc index 47563fa5..4fe2d17a 100644 --- a/test/options_test.cc +++ b/test/options_test.cc @@ -1,5 +1,7 @@ #include "benchmark/benchmark_api.h" -#include "sleep.h" + +#include +#include void BM_basic(benchmark::State& state) { while (state.KeepRunning()) { @@ -7,8 +9,14 @@ void BM_basic(benchmark::State& state) { } void BM_basic_slow(benchmark::State& state) { + + int milliseconds = state.range_x(); + std::chrono::duration sleep_duration { + static_cast(milliseconds) + }; + while (state.KeepRunning()) { - benchmark::SleepForMilliseconds(state.range_x()); + std::this_thread::sleep_for(sleep_duration); } }