精準測量程式碼片段執行時間是效能優化基礎。本文實作 Timer 類,支援多標籤並行計時、微秒精度、自動格式化輸出,零依賴、極輕量,適合開發環境即時偵測瓶頸。
db_query, api_call, render)。hrtime(true) (PHP 7.3+) 納秒級單調時鐘,避免系統時間調整影響。start/end 疊加總耗時。getTime() 回傳浮點秒,printTime() 直接輸出毫秒格式。<?php
class Timer {
private array $starts = [];
private array $ends = [];
private array $totals = []; // 疊加總時間
private string $defaultKey = '_default';
private string $prefix = 'timer_';
/** 開始計時 */
public function start(string $key = ''): void {
$key = $this->resolveKey($key);
$this->starts[$key] = hrtime(true);
}
/** 結束計時並疊加 */
public function end(string $key = ''): void {
$key = $this->resolveKey($key);
if (!isset($this->starts[$key])) return; // 未配對 start 忽略
$elapsed = (hrtime(true) - $this->starts[$key]) / 1e9; // 納秒轉秒
$this->totals[$key] = ($this->totals[$key] ?? 0) + $elapsed;
unset($this->starts[$key]);
}
/** 獲取總耗時 (秒) */
public function getTime(string $key = ''): float {
$key = $this->resolveKey($key);
return $this->totals[$key] ?? 0;
}
/** 格式化輸出毫秒 */
public function printTime(string $key = '', int $precision = 3): void {
$key = $this->resolveKey($key);
$ms = $this->getTime($key) * 1000;
$label = $key === $this->defaultKey ? 'Total' : $key;
printf("%s: %.{$precision}f ms\n", $label, $ms);
}
/** 獲取所有計時摘要 */
public function getSummary(): array {
$summary = [];
foreach ($this->totals as $k => $v) {
$label = $k === $this->defaultKey ? 'Total' : $k;
$summary[$label] = round($v * 1000, 3); // ms
}
return $summary;
}
/** 重置所有計時 */
public function reset(): void {
$this->starts = $this->ends = $this->totals = [];
}
private function resolveKey(string $key): string {
return $key === '' ? $this->defaultKey : $this->prefix . $key;
}
}
?>
<?php
require 'Timer.php';
$timer = new Timer();
// 整體計時
$timer->start();
// 資料庫查詢模擬
$timer->start('db_query');
usleep(mt_rand(50000, 200000)); // 50-200ms
$timer->end('db_query');
// 外部 API 呼叫模擬
$timer->start('api_call');
usleep(mt_rand(100000, 300000));
$timer->end('api_call');
// 視圖渲染模擬
$timer->start('render');
usleep(mt_rand(10000, 50000));
$timer->end('render');
$timer->end(); // 結束整體
// 輸出各區塊耗時
$timer->printTime('db_query');
$timer->printTime('api_call');
$timer->printTime('render');
$timer->printTime(); // Total
// 獲取摘要陣列 (適合記錄日誌/監控上報)
$summary = $timer->getSummary();
/*
Array
(
[db_query] => 123.456
[api_call] => 234.567
[render] => 34.567
[Total] => 392.590
)
*/
error_log('Request Timing: ' . json_encode($summary));
?>
<?php
// Laravel 風格中介軟體範例
class TimingMiddleware {
public function handle($request, Closure $next) {
$timer = new Timer();
$timer->start('total');
// 路由解析
$timer->start('routing');
$response = $next($request);
$timer->end('routing');
// 響應發送前記錄
$timer->end('total');
$summary = $timer->getSummary();
// 註入 Header 供前端/監控讀取
$response->headers->set('X-Timing-Total', $summary['Total']);
$response->headers->set('X-Timing-Detail', json_encode($summary));
return $response;
}
}
?>
| 函式 | 精度 | 單調性 | PHP 版本 | 適用場景 |
|---|---|---|---|---|
hrtime(true) | 納秒 (1e-9 秒) | ✅ 單調時鐘,不受 NTP/手動調整影響 | 7.3+ | 高精度效能分析、基準測試 |
microtime(true) | 微秒 (1e-6 秒) | ❌ 受系統時間影響 | 所有 | 相容舊版本、一般日誌記錄 |
start/end 約 **50-100 奈秒**,可忽略不計。Timer 類以 hrtime() 為核心,提供微秒級精度、多標籤隔離、疊加計時與即時輸出,是 PHP 效能分析、API 耗時監控、慢查詢定位的輕量利器。