catch_chronometer.hpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. // User-facing chronometer
  9. #ifndef TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED
  10. #define TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED
  11. #include "catch_clock.hpp"
  12. #include "catch_optimizer.hpp"
  13. #include "detail/catch_complete_invoke.hpp"
  14. #include "../catch_meta.hpp"
  15. namespace Catch {
  16. namespace Benchmark {
  17. namespace Detail {
  18. struct ChronometerConcept {
  19. virtual void start() = 0;
  20. virtual void finish() = 0;
  21. virtual ~ChronometerConcept() = default;
  22. };
  23. template <typename Clock>
  24. struct ChronometerModel final : public ChronometerConcept {
  25. void start() override { started = Clock::now(); }
  26. void finish() override { finished = Clock::now(); }
  27. ClockDuration<Clock> elapsed() const { return finished - started; }
  28. TimePoint<Clock> started;
  29. TimePoint<Clock> finished;
  30. };
  31. } // namespace Detail
  32. struct Chronometer {
  33. public:
  34. template <typename Fun>
  35. void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }
  36. int runs() const { return k; }
  37. Chronometer(Detail::ChronometerConcept& meter, int k)
  38. : impl(&meter)
  39. , k(k) {}
  40. private:
  41. template <typename Fun>
  42. void measure(Fun&& fun, std::false_type) {
  43. measure([&fun](int) { return fun(); }, std::true_type());
  44. }
  45. template <typename Fun>
  46. void measure(Fun&& fun, std::true_type) {
  47. Detail::optimizer_barrier();
  48. impl->start();
  49. for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);
  50. impl->finish();
  51. Detail::optimizer_barrier();
  52. }
  53. Detail::ChronometerConcept* impl;
  54. int k;
  55. };
  56. } // namespace Benchmark
  57. } // namespace Catch
  58. #endif // TWOBLUECUBES_CATCH_CHRONOMETER_HPP_INCLUDED