前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >不到100行代码,封装一个通用毫秒级计时器(基于RAII理念)

不到100行代码,封装一个通用毫秒级计时器(基于RAII理念)

作者头像
开源519
发布于 2025-06-15 04:10:07
发布于 2025-06-15 04:10:07
5900
代码可运行
举报
文章被收录于专栏:开源519开源519
运行总次数:0
代码可运行

不到100行代码,封装一个通用毫秒级计时器(基于RAII理念)

脚步不停,终达卓越!更多优质文章及代码资源详见公众号 《开源519》

引言

  在C/C++开发中,测量代码执行时间是性能分析、定时任务或超时检测等场景的常见需求。虽然可以直接调用系统接口实现,但这种方式重复代码多、可维护性差。

  高质量的程序员会倾向于将其封装为一个结构清晰、使用直观的类,以提升代码复用性和可读性,同时便于统一管理和功能扩展。面对此类需求,RAII(Resource Acquisition Is Initialization) 原则恰好为设计高效、可靠的计时器提供了理想的理论基础。

RAII,也称为“资源获取就是初始化”,是c++等编程语言常用的管理资源、避免内存泄露的方法。它保证在任何情况下,使用对象时先构造对象,最后析构对象。

需求分析

  基于日常开发对于计时器的使用需求,大致如下:

  • 使用简单 对外接口尽可能少,理论只需要提供获取执行时长的接口即可。
  • 计时精度毫秒级 提供获取时长的接口精度转换至毫秒级。
  • 可复用性强 提供一套统一且稳定的接口,确保在不同项目或模块中可以方便地重用代码。

详细设计

  实现起来很简单,主要是在封装上做文章。

RunningTiming.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef __RUNNING_TIMING_H__
#define __RUNNING_TIMING_H__

#include <stdint.h>

class RunningTiming
{
public:
    RunningTiming();
    ~RunningTiming();
    uint64_t GetElapsedTimeInSec();
    uint64_t GetElapsedTimeInMSec();

private:
    uint64_t GetCurTimeInMSec();

private:
    uint64_t mStartTimeInMSec;
};

#endif // __RUNNING_TIMING_H__

RunningTiming.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <time.h>
#include <sys/time.h>
#include "RunningTiming.h"

RunningTiming::RunningTiming()
{
    mStartTimeInMSec = GetCurTimeInMSec();
}

RunningTiming::~RunningTiming()
{
}

uint64_t RunningTiming::GetCurTimeInMSec() {
    timespec ts;
    clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
    uint64_t timeInMSec = static_cast<uint64_t>(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
    return timeInMSec;
}

uint64_t RunningTiming::GetElapsedTimeInSec()
{
    uint64_t stopTimeInMsec = GetCurTimeInMSec();
    return (stopTimeInMsec - mStartTimeInMSec) / 1000;
}

uint64_t RunningTiming::GetElapsedTimeInMSec() {
    uint64_t stopTimeInMsec = GetCurTimeInMSec();
    return stopTimeInMsec - mStartTimeInMSec;
}

实现思路

  • 构造即初始化 RunningTiming 类在构造时即自动记录起始时间,无需额外调用初始化接口,减少使用步骤,提升易用性。
  • 按需提供精度接口 根据实际需求,封装两个获取时间间隔的接口:秒级和毫秒级,便于不同场景下直接使用合适精度。
  • 统计代码执行时长 计时范围是从 RunningTiming 对象定义开始,到调用 GetElapsedTimexxx 为止的时间跨度,用于统计该时间段内代码的执行耗时。

实例使用

  因为对外接口单一,因此使用起来很方便

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    RunningTiming timer;
    usleep(100 * 1000); // 休眠 100 毫秒
    uint64_t elapsedTime = timer.GetElapsedTimeInMSec();
}

总结

  • 在 C++ 开发中,直接调用原生接口实现工具类功能虽可行,但往往不够简洁,使用成本高。对于这类问题,应通过封装优化,提升易用性和可维护性。
  • RAII 设计理念非常适合封装独立、无外部依赖的工具类。它能将资源生命周期与对象生命周期绑定,自动管理资源。但需注意:RAII 的前提是初始化必须成功,若存在外部依赖或失败可能,则不适合使用。

最后

用心感悟,认真记录,写好每一篇文章,分享每一框干货。

更多文章内容包括但不限于C/C++、Linux、开发常用神器等,可进入“开源519公众号”聊天界面输入“文章目录” 或者 菜单栏选择“文章目录”查看。公众号后台聊天框输入本文标题,在线查看源码。 在聊天框输入“开源519资料” 获取Linux C/C++ 学习资料书籍。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 不到100行代码,封装一个通用毫秒级计时器(基于RAII理念)
    • 引言
    • 需求分析
    • 详细设计
    • 实例使用
    • 总结
    • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档