1 /* 2 * Created by Joachim on 16/04/2019. 3 * Adapted from donated nonius code. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 */ 8 9 // User-facing chronometer 10 11 #ifndef TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED 12 #define TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED 13 14 #include "catch_clock.hpp" 15 #include "catch_optimizer.hpp" 16 #include "detail/catch_complete_invoke.hpp" 17 #include "../catch_meta.hpp" 18 19 namespace Catch { 20 namespace Benchmark { 21 namespace Detail { 22 struct ChronometerConcept { 23 virtual void start() = 0; 24 virtual void finish() = 0; 25 virtual ~ChronometerConcept() = default; 26 }; 27 template <typename Clock> 28 struct ChronometerModel final : public ChronometerConcept { startCatch::Benchmark::Detail::ChronometerModel29 void start() override { started = Clock::now(); } finishCatch::Benchmark::Detail::ChronometerModel30 void finish() override { finished = Clock::now(); } 31 elapsedCatch::Benchmark::Detail::ChronometerModel32 ClockDuration<Clock> elapsed() const { return finished - started; } 33 34 TimePoint<Clock> started; 35 TimePoint<Clock> finished; 36 }; 37 } // namespace Detail 38 39 struct Chronometer { 40 public: 41 template <typename Fun> measureCatch::Benchmark::Chronometer42 void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); } 43 runsCatch::Benchmark::Chronometer44 int runs() const { return k; } 45 ChronometerCatch::Benchmark::Chronometer46 Chronometer(Detail::ChronometerConcept& meter, int k) 47 : impl(&meter) 48 , k(k) {} 49 50 private: 51 template <typename Fun> measureCatch::Benchmark::Chronometer52 void measure(Fun&& fun, std::false_type) { 53 measure([&fun](int) { return fun(); }, std::true_type()); 54 } 55 56 template <typename Fun> measureCatch::Benchmark::Chronometer57 void measure(Fun&& fun, std::true_type) { 58 Detail::optimizer_barrier(); 59 impl->start(); 60 for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i); 61 impl->finish(); 62 Detail::optimizer_barrier(); 63 } 64 65 Detail::ChronometerConcept* impl; 66 int k; 67 }; 68 } // namespace Benchmark 69 } // namespace Catch 70 71 #endif // TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED 72