在程式開發中,效能分析、日誌記錄、定時任務等場景都需要精確獲取時間並計算差值。C/C++ 提供了從秒級到納秒級的多種方案,本文整理三種最常用的方法,涵蓋標準庫、POSIX 及 Windows 平台特有 API。
<time.h> —— 秒級精度,跨平台適用於不需要高精度的場景,如記錄程式啟動耗時、簡單的超時判斷。
time_t time(time_t *timer):獲取當前日曆時間(自 1970-01-01 00:00:00 UTC 的秒數)。double difftime(time_t end, time_t start):計算兩時間點差值(秒),返回 double 型別。#include <time.h>
#include <stdio.h>
#include <unistd.h> // Linux sleep
int main() {
time_t start, end;
time(&start);
sleep(1); // Linux: 秒;Windows 需用 Sleep(1000) 並含 windows.h
time(&end);
double cost = difftime(end, start);
printf("耗時: %f 秒\n", cost); // 輸出 1.000000
return 0;
}
跨平台注意:Windows 下睡眠函數為 Sleep(毫秒)(大寫 S),需含 <windows.h>;Linux 下 sleep(秒)、usleep(微秒)。
<sys/time.h> —— 微秒級精度,Linux/Unix 通用struct timeval 提供秒(tv_sec)與微秒(tv_usec)兩欄位,精度達 1μs,適合網路延遲測量、高效能日誌時間戳。
int gettimeofday(struct timeval *tv, struct timezone *tz):獲取當前時間,tz 通常傳 NULL。(end.tv_sec - start.tv_sec) * 1e6 + (end.tv_usec - start.tv_usec) 微秒。#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main() {
struct timeval start, end;
gettimeofday(&start, NULL);
usleep(500000); // 0.5 秒
gettimeofday(&end, NULL);
long diff_us = (end.tv_sec - start.tv_sec) * 1000000L + (end.tv_usec - start.tv_usec);
printf("耗時: %ld 微秒 (%.3f 毫秒)\n", diff_us, diff_us / 1000.0);
return 0;
}
<chrono> —— 納秒級精度,型別安全,現代 C++ 首選std::chrono 提供型別安全的時間點(time_point)、持續時間(duration)與時鐘(clock),支援編譯期單位換算,避免手動換算錯誤。
steady_clock:單調時鐘,受系統調整時間影響,適合測量間隔。high_resolution_clock:最高精度時鐘(通常為 steady_clock 別名)。duration_cast:單位轉換(納秒、微秒、毫秒、秒)。#include <chrono>
#include <iostream>
#include <thread>
int main() {
using namespace std::chrono;
auto start = high_resolution_clock::now();
std::this_thread::sleep_for(milliseconds(100)); // C++11 睡眠
auto end = high_resolution_clock::now();
auto diff_ns = duration_cast<nanoseconds>(end - start).count();
auto diff_ms = duration_cast<milliseconds>(end - start).count();
std::cout << "耗時: " << diff_ns << " ns (" << diff_ms << " ms)" << std::endl;
return 0;
}
QueryPerformanceCounter —— 硬體計數器級精度Windows 平台最高精度計時,利用 CPU 高解析度效能計數器,精度可達納秒級,常用於遊戲引擎、即時系統。
QueryPerformanceFrequency:獲取計數器頻率(每秒計數)。QueryPerformanceCounter:獲取當前計數值。(end - start) * 1.0 / freq * 1e9 納秒。#include <windows.h>
#include <stdio.h>
int main() {
LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
Sleep(10); // 10 毫秒
QueryPerformanceCounter(&end);
double diff_ns = (double)(end.QuadPart - start.QuadPart) * 1e9 / freq.QuadPart;
printf("耗時: %.0f 納秒 (%.3f 毫秒)\n", diff_ns, diff_ns / 1e6);
return 0;
}
| 方法 | 精度 | 平台 | 適用場景 |
|---|---|---|---|
time/difftime | 秒 | 全平台 | 粗略計時、日誌時間戳 |
gettimeofday | 微秒 | Linux/Unix | 網路編程、效能分析 |
std::chrono | 納秒 | C++11 全平台 | 現代 C++ 專案首選,型別安全 |
QueryPerformanceCounter | 納秒 | Windows | 高精度需求、遊戲/即時系統 |
現代 C++ 專案建議優先使用 <chrono>;需兼容 C 或舊代碼庫時,Linux 用 gettimeofday,Windows 用 QueryPerformanceCounter。