123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
- *
- * This file is part of ZLToolKit(https://github.com/xia-chu/ZLToolKit).
- *
- * Use of this source code is governed by MIT license that can be found in the
- * LICENSE file in the root of the source tree. All contributing project authors
- * may be found in the AUTHORS file in the root of the source tree.
- */
- #ifndef UTIL_TIMETICKER_H_
- #define UTIL_TIMETICKER_H_
- #include <assert.h>
- #include "logger.h"
- #include "Util/util.h"
- namespace toolkit {
- class Ticker {
- public:
- /**
- * 此对象可以用于代码执行时间统计,以可以用于一般计时
- * @param min_ms 开启码执行时间统计时,如果代码执行耗时超过该参数,则打印警告日志
- * @param ctx 日志上下文捕获,用于捕获当前日志代码所在位置
- * @param print_log 是否打印代码执行时间
- */
- Ticker(uint64_t min_ms = 0,
- LogContextCapturer ctx = LogContextCapturer(Logger::Instance(), LWarn, __FILE__, "", __LINE__),
- bool print_log = false) : _ctx(std::move(ctx)) {
- if (!print_log) {
- _ctx.clear();
- }
- _created = _begin = getCurrentMillisecond();
- _min_ms = min_ms;
- }
- ~Ticker() {
- uint64_t tm = createdTime();
- if (tm > _min_ms) {
- _ctx << "take time:" << tm << "ms" << ", thread may be overloaded";
- } else {
- _ctx.clear();
- }
- }
- /**
- * 获取创建时间,单位毫秒
- */
- uint64_t elapsedTime() const {
- return getCurrentMillisecond() - _begin;
- }
- /**
- * 获取上次resetTime后至今的时间,单位毫秒
- */
- uint64_t createdTime() const {
- return getCurrentMillisecond() - _created;
- }
- /**
- * 重置计时器
- */
- void resetTime() {
- _begin = getCurrentMillisecond();
- }
- private:
- uint64_t _min_ms;
- uint64_t _begin;
- uint64_t _created;
- LogContextCapturer _ctx;
- };
- class SmoothTicker {
- public:
- /**
- * 此对象用于生成平滑的时间戳
- * @param reset_ms 时间戳重置间隔,没间隔reset_ms毫秒, 生成的时间戳会同步一次系统时间戳
- */
- SmoothTicker(uint64_t reset_ms = 10000) {
- _reset_ms = reset_ms;
- _ticker.resetTime();
- }
- ~SmoothTicker() {}
- /**
- * 返回平滑的时间戳,防止由于网络抖动导致时间戳不平滑
- */
- uint64_t elapsedTime() {
- auto now_time = _ticker.elapsedTime();
- if (_first_time == 0) {
- if (now_time < _last_time) {
- auto last_time = _last_time - _time_inc;
- double elapse_time = (now_time - last_time);
- _time_inc += (elapse_time / ++_pkt_count) / 3;
- auto ret_time = last_time + _time_inc;
- _last_time = (uint64_t)ret_time;
- return (uint64_t)ret_time;
- }
- _first_time = now_time;
- _last_time = now_time;
- _pkt_count = 0;
- _time_inc = 0;
- return now_time;
- }
- auto elapse_time = (now_time - _first_time);
- _time_inc += elapse_time / ++_pkt_count;
- auto ret_time = _first_time + _time_inc;
- if (elapse_time > _reset_ms) {
- _first_time = 0;
- }
- _last_time = (uint64_t)ret_time;
- return (uint64_t)ret_time;
- }
- /**
- * 时间戳重置为0开始
- */
- void resetTime() {
- _first_time = 0;
- _pkt_count = 0;
- _ticker.resetTime();
- }
- private:
- double _time_inc = 0;
- uint64_t _first_time = 0;
- uint64_t _last_time = 0;
- uint64_t _pkt_count = 0;
- uint64_t _reset_ms;
- Ticker _ticker;
- };
- #if !defined(NDEBUG)
- #define TimeTicker() Ticker __ticker(5,WarnL,true)
- #define TimeTicker1(tm) Ticker __ticker1(tm,WarnL,true)
- #define TimeTicker2(tm,log) Ticker __ticker2(tm,log,true)
- #else
- #define TimeTicker()
- #define TimeTicker1(tm)
- #define TimeTicker2(tm,log)
- #endif
- } /* namespace toolkit */
- #endif /* UTIL_TIMETICKER_H_ */
|