首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

效能測試計時器封裝:QueryPerformanceCounter 微秒級精度與多場景應用範例

     編輯:關於VC++

動機

直接呼叫 timeGetTime/GetTickCount 精度有限 (毫秒級),且在模組前後插入計時代碼導致程式碼混亂。本文封裝高精度計時器,支援巢狀計時、迴圈累加、結果自動輸出檔案。

核心 API

  • QueryPerformanceFrequency:取得硬體計數器頻率
  • QueryPerformanceCounter:取得當前計數值
  • 理論精度達微秒 (μs) 級

封裝實作

資料結構

#define BENCHMARK_MAX_COUNT 20
double gStarts[BENCHMARK_MAX_COUNT];
double gEnds[BENCHMARK_MAX_COUNT];
double gCounters[BENCHMARK_MAX_COUNT];
double dfFreq = 1.0;

初始化

void InitBenchmark() {
    ResetBenchmarkCounters(); // 陣列歸零
    GetClockFrequent();       // QueryPerformanceFrequency(&dfFreq)
}

開始/結束計時 (宏簡化呼叫)

void BMTimerStart(int iModel) {
    LARGE_INTEGER li; QueryPerformanceCounter(&li);
    gStarts[iModel] = li.QuadPart;
}
#define BM_START(t) BMTimerStart(t)

void BMTimerEnd(int iModel) {
    LARGE_INTEGER li; QueryPerformanceCounter(&li);
    gEnds[iModel] = li.QuadPart;
    gCounters[iModel] += ((gEnds[iModel] - gStarts[iModel]) / dfFreq) * 1000000.0; // 累加 μs
}
#define BM_END(t) BMTimerEnd(t)

關鍵點:使用 += 而非 =,支援同一模組多次呼叫累加 (如迴圈內)。

結果輸出

void WriteData() {
    // 將 gCounters 所有值寫入文字檔 (如 D:\log.txt)
}

應用場景範例

1. 多模組巢狀計時

BM_START(0); // 外層
    BM_START(1); // 內層模組 A
    // ... code ...
    BM_END(1);
    BM_START(2); // 內層模組 B
    // ... code ...
    BM_END(2);
BM_END(0);

2. 迴圈內每次運算計時


for (int i=1; i<=20; i++) {
    BM_START(0);
    double result = Factorial(i);
    BM_END(0);
}
WriteData(); // 輸出每次階乘耗時

結果輸出範例 (圖5):每行一個模組的微秒數。

3. 迴圈累加計時 (兩種寫法)

寫法 A - 外層包裹 (圖6):

BM_START(0);
for (int i=0; i<10000; i++) Factorial(20);
BM_END(0);

寫法 B - 內層累加 (圖7):

for (int i=0; i<10000; i++) {
    BM_START(0);
    Factorial(20);
    BM_END(0); // += 累加
}

兩者結果相同 (圖8),寫法 B 更靈活可插入任意程式碼區塊。

擴充建議

  • 封裝為 CBenchmark 類別,支援 RAII 風格 (CAutoTimer 建構/解構自動計時)
  • 增加呼叫次數統計、平均/最大/最小值分析
  • 支援多執行緒環境 (TLS 儲存計數器)
  • 整合至單元測試框架自動效能回歸
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved