TimeTicker.h 4.0 KB

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