statistic_timer.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #ifndef SOPHIAR2_STATISTIC_TIMER_HPP
  2. #define SOPHIAR2_STATISTIC_TIMER_HPP
  3. #include "core/timestamp_helper.hpp"
  4. #include <boost/accumulators/accumulators.hpp>
  5. #include <boost/accumulators/statistics/max.hpp>
  6. #include <boost/accumulators/statistics/min.hpp>
  7. #include <boost/accumulators/statistics/stats.hpp>
  8. #include <boost/accumulators/statistics/variance.hpp>
  9. #include <fmt/format.h>
  10. #include <cassert>
  11. #include <cmath>
  12. #include <string>
  13. #include <type_traits>
  14. namespace sophiar {
  15. struct statistic_timer_single_shot_tag;
  16. struct statistic_timer_start_stop_tag;
  17. template<typename ModeTag>
  18. class statistic_timer {
  19. public:
  20. void start(timestamp_type current_ts = current_timestamp());
  21. template<typename CurrentModeTag = ModeTag>
  22. std::enable_if_t<std::is_same_v<CurrentModeTag, statistic_timer_start_stop_tag>>
  23. stop(timestamp_type current_ts = current_timestamp()) {
  24. assert(is_running);
  25. is_running = false;
  26. accumulator(current_ts - last_ts);
  27. }
  28. void reset() {
  29. accumulator = {};
  30. }
  31. auto get_count() const {
  32. return boost::accumulators::count(accumulator);
  33. }
  34. auto get_min() const {
  35. return boost::accumulators::min(accumulator);
  36. }
  37. auto get_max() const {
  38. return boost::accumulators::max(accumulator);
  39. }
  40. auto get_mean() const {
  41. return boost::accumulators::mean(accumulator);
  42. }
  43. auto get_std() const {
  44. return std::sqrt(boost::accumulators::variance(accumulator));
  45. }
  46. std::string to_string() const;
  47. private:
  48. using float_type = double;
  49. using accumulator_type = boost::accumulators::accumulator_set<
  50. float_type, boost::accumulators::stats<
  51. boost::accumulators::tag::min,
  52. boost::accumulators::tag::max,
  53. boost::accumulators::tag::variance> >;
  54. accumulator_type accumulator;
  55. bool is_running = false;
  56. timestamp_type last_ts = 0;
  57. };
  58. template<>
  59. void statistic_timer<statistic_timer_single_shot_tag>::start(timestamp_type current_ts) {
  60. if (last_ts != 0) {
  61. accumulator(current_ts - last_ts);
  62. }
  63. last_ts = current_ts;
  64. }
  65. template<>
  66. void statistic_timer<statistic_timer_start_stop_tag>::start(timestamp_type current_ts) {
  67. assert(!is_running);
  68. is_running = true;
  69. last_ts = current_ts;
  70. }
  71. template<>
  72. std::string statistic_timer<statistic_timer_single_shot_tag>::to_string() const {
  73. return fmt::format("Cnt: {}, "
  74. "Min: {:.3f}ms({:.3f}Hz), Max: {:.3f}ms({:.3f}Hz), "
  75. "Mean: {:.3f}({:.3f})ms({:.3f}Hz)",
  76. get_count(),
  77. get_min() / 1e3, 1e6 / get_min(),
  78. get_max() / 1e3, 1e6 / get_max(),
  79. get_mean() / 1e3, get_std() / 1e3, 1e6 / get_mean());
  80. }
  81. template<>
  82. std::string statistic_timer<statistic_timer_start_stop_tag>::to_string() const {
  83. return fmt::format("Cnt: {}, Min: {:.3f}ms, Max: {:.3f}ms, Mean: {:.3f}({:.3f})ms",
  84. get_count(), get_min() / 1e3, get_max() / 1e3,
  85. get_mean() / 1e3, get_std() / 1e3);
  86. }
  87. }
  88. #endif //SOPHIAR2_STATISTIC_TIMER_HPP