SoftGLRender源码:Timer类
目录
特性
文件:Base/Timer.h, Timer.cpp
这部分有2个类协作:Timer, ScopedTimer.
- Timer 记录、计算一段时间长度,不提供超时回调.
- ScopedTimer 通过RAII管理Timer资源,计算ScopedTimer类对象从构造到析构的时间.
获取时间:用<chrono>库提供的steady_clock::now()
std::chrono::time_point<std::chrono::steady_clock> start = std::chrono::steady_clock::now();
Timer类
计时功能
Timer类实现计时功能. 包含2个数据成员:start_, end_,分别用于记录起始时间、结束时间.
// Timer.h
class Timer {
public:
void start(); // 开始计时
void stop(); // 结束计时
int64_t elapseMillis() const;
private:
std::chrono::time_point<std::chrono::steady_clock> start_;
std::chrono::time_point<std::chrono::steady_clock> end_;
};
记录起始时间:
void Timer::start() {
start_ = std::chrono::steady_clock::now();
}
记录结束时间:
void Timer::stop() {
end_ = std::chrono::steady_clock::now();
}
计算时间差:
int64_t Timer::elapseMillis() const {
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_ - start_); // 单位:ms
return duration.count();
}
3种计时:steady_clock, system_clock, high_resolution_clock
<chrono>库提供了3种时钟:steady_clock, system_clock, high_resolution_clock. 都能用于计时.
它们的区别:
-
steady_clock 稳定时钟
- 单调递增的时钟,不受系统时间调整的影响
- 适用于需要测量时间间隔的场景,如性能分析、超时计算等,时间不会倒退
- 设计初衷是稳定且单调,每次调用
now()得到的时间都比之前的大
-
system_clock 系统时钟
- 系统范围的实时时钟(即“挂钟时间”),与实际时间(如UTC时间)相关
- 适用于需要与日历交互的场景,如记录日志、文件时间戳等
- 可能受系统时间调整的影响,例如用户手动修改系统时间或NTP同步
-
high_resolution_clock 高精度时钟
- 提供尽可能高的时间分辨率(精度),适用于需要纳秒或微秒级计时的场景,如性能分析、基准测试
- 大多数实现中,可能是steady_clock或system_clock别名,依赖于底层实现
虽然steady_clock和system_clock,都能返回time_point类型数据,表示时间点信息. 但system_clock::time_point能转换成std::time_t,进而用C标准库函数(如std::localtime)转换为日历信息;
e.g. 将system_clock::time_point转换为日历信息
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
但是steady_clock::time_point无法转换,仅能计算时间差.
e.g. 用steady_clock::time_point计算时间差
auto start = std::chrono::steady_clock::now();
// ...操作...
auto end = std::chrono::steady_clock::now();
auto duration = end - start; // 计算时间间隔
ScopedTimer类
自动计时功能
利用RAII技术实现 作用域计时器. 核心功能:构造时,开始计时;析构时,结束计时,并输出耗时(ms)到日志系统.
class ScopedTimer {
public:
// 构造时,需要指定一个字符串作为tag_
ScopedTimer(const char* str) : tag_(str) {
timer_.start();
}
~ScopedTimer() {
timer_.stop();
LOGD("TIMER %s: cost : %lld ms", tag_.c_str(), timer_.elapseMillis());
}
explicit operator bool() {
return true;
}
private:
Timer timer_; // 定时器
std::string tag_; // 定时器标记
};
定时器标记tag_,是为了在log中标识定时器,方便用户查看.
内联宏使用ScopedTimer
为方便用户使用ScopedTimer计时,提供了一组宏
#ifndef NDEBUG
# define FUNCTION_TIMED(X) SoftGL::ScopedTimer _functionTimer = (X)
# define SCOPED_TIMED(X) if (SoftGL::ScopedTimer _scopeTimer = (X))
#else
# define FUNCTION_TIMED(X)
# define SCOPED_TIMED(X)
#endif // !NDEBUG
这样,用户只需要在需要计时的作用域使用该宏即可.
{
FUNCTION_TIMED("VKContext::create");
...
} // 离开作用域,析构ScopedTimer对象,自动记录这段代码块的执行时间到日志

浙公网安备 33010602011771号