不到100行代碼,封裝一個通用毫秒級計時器(基于RAII思想)

不到100行代碼,封裝一個通用毫秒級計時器(基于RAII思想)

[TOC]

腳步不停,終達卓越!更多優(yōu)質文章及代碼資源詳見公眾號 《開源519》

引言

? 在C/C++開發(fā)中,測量代碼執(zhí)行時間是性能分析、定時任務或超時檢測等場景的常見需求。雖然可以直接調用系統(tǒng)接口實現,但這種方式重復代碼多、可維護性差。

? 高質量的程序員會傾向于將其封裝為一個結構清晰、使用直觀的類,以提升代碼復用性和可讀性,同時便于統(tǒng)一管理和功能擴展。面對此類需求,RAII(Resource Acquisition Is Initialization) 原則恰好為設計高效、可靠的計時器提供了理想的理論基礎。

RAII,也稱為“資源獲取就是初始化”,是c++等編程語言常用的管理資源、避免內存泄露的方法。它保證在任何情況下,使用對象時先構造對象,最后析構對象。

需求分析

? 基于日常開發(fā)對于計時器的使用需求,大致如下:

  • 使用簡單
    對外接口盡可能少,理論只需要提供獲取執(zhí)行時長的接口即可。
  • 計時精度毫秒級
    提供獲取時長的接口精度轉換至毫秒級。
  • 可復用性強
    提供一套統(tǒng)一且穩(wěn)定的接口,確保在不同項目或模塊中可以方便地重用代碼。

詳細設計

? 實現起來很簡單,主要是在封裝上做文章。

RunningTiming.h

#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

#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 類在構造時即自動記錄起始時間,無需額外調用初始化接口,減少使用步驟,提升易用性。
  • 按需提供精度接口
    根據實際需求,封裝兩個獲取時間間隔的接口:秒級和毫秒級,便于不同場景下直接使用合適精度。
  • 統(tǒng)計代碼執(zhí)行時長
    計時范圍是從 RunningTiming 對象定義開始,到調用 GetElapsedTimexxx 為止的時間跨度,用于統(tǒng)計該時間段內代碼的執(zhí)行耗時。

實例使用

? 因為對外接口單一,因此使用起來很方便

{
    RunningTiming timer;
    usleep(100 * 1000); // 休眠 100 毫秒
    uint64_t elapsedTime = timer.GetElapsedTimeInMSec();
}

總結

  • 在 C++ 開發(fā)中,直接調用原生接口實現工具類功能雖可行,但往往不夠簡潔,使用成本高。對于這類問題,應通過封裝優(yōu)化,提升易用性和可維護性。

  • RAII 設計理念非常適合封裝獨立、無外部依賴的工具類。它能將資源生命周期與對象生命周期綁定,自動管理資源。但需注意:RAII 的前提是初始化必須成功,若存在外部依賴或失敗可能,則不適合使用。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容