TimeTicker.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef UTIL_TIMETICKER_H_
  11. #define UTIL_TIMETICKER_H_
  12. #include <cassert>
  13. #include "logger.h"
  14. namespace toolkit {
  15. class Ticker {
  16. public:
  17. /**
  18. * 此对象可以用于代码执行时间统计,以可以用于一般计时
  19. * @param min_ms 开启码执行时间统计时,如果代码执行耗时超过该参数,则打印警告日志
  20. * @param ctx 日志上下文捕获,用于捕获当前日志代码所在位置
  21. * @param print_log 是否打印代码执行时间
  22. */
  23. Ticker(uint64_t min_ms = 0,
  24. LogContextCapture ctx = LogContextCapture(Logger::Instance(), LWarn, __FILE__, "", __LINE__),
  25. bool print_log = false) : _ctx(std::move(ctx)) {
  26. if (!print_log) {
  27. _ctx.clear();
  28. }
  29. _created = _begin = getCurrentMillisecond();
  30. _min_ms = min_ms;
  31. }
  32. ~Ticker() {
  33. uint64_t tm = createdTime();
  34. if (tm > _min_ms) {
  35. _ctx << "take time: " << tm << "ms" << ", thread may be overloaded";
  36. } else {
  37. _ctx.clear();
  38. }
  39. }
  40. /**
  41. * 获取上次resetTime后至今的时间,单位毫秒
  42. */
  43. uint64_t elapsedTime() const {
  44. return getCurrentMillisecond() - _begin;
  45. }
  46. /**
  47. * 获取从创建至今的时间,单位毫秒
  48. */
  49. uint64_t createdTime() const {
  50. return getCurrentMillisecond() - _created;
  51. }
  52. /**
  53. * 重置计时器
  54. */
  55. void resetTime() {
  56. _begin = getCurrentMillisecond();
  57. }
  58. private:
  59. uint64_t _min_ms;
  60. uint64_t _begin;
  61. uint64_t _created;
  62. LogContextCapture _ctx;
  63. };
  64. class SmoothTicker {
  65. public:
  66. /**
  67. * 此对象用于生成平滑的时间戳
  68. * @param reset_ms 时间戳重置间隔,没间隔reset_ms毫秒, 生成的时间戳会同步一次系统时间戳
  69. */
  70. SmoothTicker(uint64_t reset_ms = 10000) {
  71. _reset_ms = reset_ms;
  72. _ticker.resetTime();
  73. }
  74. ~SmoothTicker() {}
  75. /**
  76. * 返回平滑的时间戳,防止由于网络抖动导致时间戳不平滑
  77. */
  78. uint64_t elapsedTime() {
  79. auto now_time = _ticker.elapsedTime();
  80. if (_first_time == 0) {
  81. if (now_time < _last_time) {
  82. auto last_time = _last_time - _time_inc;
  83. double elapse_time = (now_time - last_time);
  84. _time_inc += (elapse_time / ++_pkt_count) / 3;
  85. auto ret_time = last_time + _time_inc;
  86. _last_time = (uint64_t) ret_time;
  87. return (uint64_t) ret_time;
  88. }
  89. _first_time = now_time;
  90. _last_time = now_time;
  91. _pkt_count = 0;
  92. _time_inc = 0;
  93. return now_time;
  94. }
  95. auto elapse_time = (now_time - _first_time);
  96. _time_inc += elapse_time / ++_pkt_count;
  97. auto ret_time = _first_time + _time_inc;
  98. if (elapse_time > _reset_ms) {
  99. _first_time = 0;
  100. }
  101. _last_time = (uint64_t) ret_time;
  102. return (uint64_t) ret_time;
  103. }
  104. /**
  105. * 时间戳重置为0开始
  106. */
  107. void resetTime() {
  108. _first_time = 0;
  109. _pkt_count = 0;
  110. _ticker.resetTime();
  111. }
  112. private:
  113. double _time_inc = 0;
  114. uint64_t _first_time = 0;
  115. uint64_t _last_time = 0;
  116. uint64_t _pkt_count = 0;
  117. uint64_t _reset_ms;
  118. Ticker _ticker;
  119. };
  120. #if !defined(NDEBUG)
  121. #define TimeTicker() Ticker __ticker(5,WarnL,true)
  122. #define TimeTicker1(tm) Ticker __ticker1(tm,WarnL,true)
  123. #define TimeTicker2(tm, log) Ticker __ticker2(tm,log,true)
  124. #else
  125. #define TimeTicker()
  126. #define TimeTicker1(tm)
  127. #define TimeTicker2(tm,log)
  128. #endif
  129. } /* namespace toolkit */
  130. #endif /* UTIL_TIMETICKER_H_ */