利用 建構函數啟動計時、解構函數停止並報告 的 RAII 模式,實現零侵入式的程式碼區塊效能測量。無需手動配對 start/stop,離開作用域自動輸出結果,彈性支援函數、迴圈、任意區塊。
#include
#include
#include
class Stopwatch {
std::clock_t start_;
std::string label_;
public:
explicit Stopwatch(const std::string& label = "") : start_(std::clock()), label_(label) {}
~Stopwatch() {
std::clock_t end = std::clock();
double elapsed_ms = double(end - start_) * 1000.0 / CLOCKS_PER_SEC;
std::cout << (label_.empty() ? "Operation" : label_)
<< " took " << elapsed_ms << " ms" << std::endl;
}
// 禁止複製,避免雙重報告
Stopwatch(const Stopwatch&) = delete;
Stopwatch& operator=(const Stopwatch&) = delete;
};
// 使用範例
void demo() {
{
Stopwatch sw("Matrix multiplication");
// ... 執行矩陣乘法 ...
} // 自動輸出: "Matrix multiplication took 12.34 ms"
{
Stopwatch sw; // 無標籤
for (int i = 0; i < 1000000; ++i) { /* ... */ }
} // 自動輸出: "Operation took 5.67 ms"
}
#include
#include
class ScopedTimer {
using Clock = std::chrono::high_resolution_clock;
Clock::time_point start_;
std::string label_;
std::function logger_; // 自訂輸出
public:
ScopedTimer(const std::string& label,
std::function logger = nullptr)
: start_(Clock::now()), label_(label),
logger_(logger ? logger : [](const std::string& l, double ms) {
std::cout << l << ": " << ms << " ms\n";
}) {}
~ScopedTimer() {
auto end = Clock::now();
double ms = std::chrono::duration(end - start_).count();
logger_(label_.empty() ? "ScopedTimer" : label_, ms);
}
ScopedTimer(const ScopedTimer&) = delete;
ScopedTimer& operator=(const ScopedTimer&) = delete;
};
// 使用:記錄到檔案、發送到監控系統等
void advanced_demo() {
ScopedTimer sw("DB query", [](const std::string& l, double ms) {
// 寫入 log 檔或推送 metrics
std::clog << "[PERF] " << l << " = " << ms << " ms" << std::endl;
});
// ... 執行查詢 ...
}
| 優點 | 缺點/注意 |
|---|---|
| 零樣板代碼,離開作用域自動測量 | 僅適合區塊級測量,不適合跨函數/非同步流程 |
| 編譯器優化不影響計時邏輯 | 極短區塊 (<1ms) 受系統時鐘解析度限制 |
| 例外安全:拋出異常時仍會觸發解構函數 | 多執行緒環境下 std::cout 輸出需自行同步 |
| 可攜性強 (標準 C++) | 若在效能熱點大量使用,建構/解構開銷可能干擾測量 |
// 手動版 - 易遺漏、不例外安全
clock_t t1 = clock();
// ... code ...
clock_t t2 = clock();
std::cout << (t2-t1)*1000.0/CLOCKS_PER_SEC << " ms\n";
Stopwatch/ScopedTimer 是 C++ 中實現「執行時間測量」最地道的方式:語意清晰、例外安全、零維護成本。專案中建議封裝為通用工具類,配合宏或 Lambda 進一步簡化呼叫端代碼。