#pragma once #include "testing/testing.hpp" #include "testing/testregister.hpp" #include "base/timer.hpp" #include namespace base { class BenchmarkNTimes { public: BenchmarkNTimes(int repeatCount, double maxSecondsToSucceed) : m_repeatCount(repeatCount), m_maxSecondsToSucceed(maxSecondsToSucceed), m_iteration(0) { } ~BenchmarkNTimes() { double const secondsElapsed = m_timer.ElapsedSeconds(); TEST_GREATER(m_repeatCount, 0, ()); TEST_LESS_OR_EQUAL(secondsElapsed, m_maxSecondsToSucceed, (m_repeatCount)); std::cout << secondsElapsed << "s total"; if (secondsElapsed > 0) { std::cout << ", " << static_cast(m_repeatCount / secondsElapsed) << "/s, "; /* if (secondsElapsed / m_repeatCount * 1000 >= 10) std::cout << static_cast(secondsElapsed / m_repeatCount * 1000) << "ms each"; else */ if (secondsElapsed / m_repeatCount * 1000000 >= 10) std::cout << static_cast(secondsElapsed / m_repeatCount * 1000000) << "us each"; else std::cout << static_cast(secondsElapsed / m_repeatCount * 1000000000) << "ns each"; } std::cout << " ..."; } int Iteration() const { return m_iteration; } bool ContinueIterating() const { return m_iteration < m_repeatCount; } void NextIteration() { ++m_iteration; } private: int const m_repeatCount; double const m_maxSecondsToSucceed; int m_iteration; Timer m_timer; }; } // namespace base #define BENCHMARK_TEST(name) \ void Benchmark_##name(); \ TestRegister g_BenchmarkRegister_##name("Benchmark::" #name, __FILE__, &Benchmark_##name); \ void Benchmark_##name() #define BENCHMARK_N_TIMES(times, maxTimeToSucceed) \ for (::base::BenchmarkNTimes benchmark(times, maxTimeToSucceed); benchmark.ContinueIterating(); \ benchmark.NextIteration())