萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 計算頁面載入執行時間的多種方法與精確度分析

PHP 頁面執行時間測量:microtime、類別封裝與精確度考量

測量腳本執行時間常用 microtime() 取得微秒級時間戳。但需注意:microtime() 回傳的是**進程啟動後的時間**,若有多個 PHP 腳本串聯執行 (include、框架流程),測得的是**整個請求的壁鐘時間**,不一定等於單一腳本的 CPU 時間。

基礎函數封裝

<?php
function getMicrotime(): float {
    [$usec, $sec] = explode(' ', microtime());
    return (float)$usec + (float)$sec;
}

// 使用
$start = getMicrotime();
// ... 程式碼 ...
$end = getMicrotime();
echo '執行時間: ' . round($end - $start, 4) . ' 秒';
?>

物件導向計時器類別 (可重複使用、多段計時)

<?php
class Timer {
    private float $startTime = 0;
    private float $stopTime = 0;
    private ?float $elapsed = null;

    public function start(): void {
        $this->startTime = microtime(true); // PHP 5.0+ 直接回傳 float
        $this->elapsed = null;
    }

    public function stop(): void {
        $this->stopTime = microtime(true);
    }

    public function elapsed(int $precision = 4): float {
        if ($this->elapsed !== null) return $this->elapsed;
        if ($this->startTime === 0 || $this->stopTime === 0) {
            throw new LogicException('Timer not started/stopped');
        }
        $this->elapsed = round($this->stopTime - $this->startTime, $precision);
        return $this->elapsed;
    }

    public function elapsedMs(int $precision = 1): float {
        return round($this->elapsed() * 1000, $precision);
    }
}

// 使用
$timer = new Timer();
$timer->start();
// ... 業務邏輯 ...
$timer->stop();
echo "頁面執行時間: {$timer->elapsedMs()} 毫秒";
?>

簡易版類別 (舊風格)

<?php
class Runtime {
    private $start = 0;
    private $stop = 0;

    public function start() { $this->start = microtime(true); }
    public function stop()  { $this->stop  = microtime(true); }
    public function spent() { return round(($this->stop - $this->start) * 1000, 1); } // ms
}

$rt = new Runtime();
$rt->start();
for ($i = 0; $i < 1000000; $i++) { $a = $i; }
$rt->stop();
echo "執行時間: {$rt->spent()} 毫秒";
?>

進階:分段計時 (Profiling 關鍵點)

<?php
class Profiler {
    private array $marks = [];
    private array $spans = [];

    public function mark(string $name): void {
        $this->marks[$name] = microtime(true);
    }

    public function measure(string $name, string $startMark, string $endMark): float {
        if (!isset($this->marks[$startMark], $this->marks[$endMark])) {
            throw new InvalidArgumentException('Mark not found');
        }
        $duration = $this->marks[$endMark] - $this->marks[$startMark];
        $this->spans[$name] = $duration;
        return $duration;
    }

    public function getReport(): array {
        return $this->spans;
    }
}

$prof = new Profiler();
$prof->mark('start');
// DB 查詢
$prof->mark('db_done');
// 模板渲染
$prof->mark('render_done');

echo "DB: " . $prof->measure('db', 'start', 'db_done') * 1000 . " ms\n";
echo "Render: " . $prof->measure('render', 'db_done', 'render_done') * 1000 . " ms\n";
echo "Total: " . $prof->measure('total', 'start', 'render_done') * 1000 . " ms\n";
?>

精確度與替代方案

  • microtime(true) 精度為微秒 (取決於 OS,Linux 通常達 1μs)。
  • hrtime() (PHP 7.3+):高解析度奈秒計時器,**單調時鐘** (不受系統時間調整影響),適合效能測量。
  • <?php
    $start = hrtime(true);
    // ...
    $elapsedNs = hrtime(true) - $start;
    echo "耗時: " . ($elapsedNs / 1_000_000) . " ms";
    ?>
  • 生產環境效能分析請用 **Xdebug Profiler**、**Blackfire**、**Tideways** 或 **OpenTelemetry**,而非手動計時。

總結

  1. 簡單需求:microtime(true) 相減即可。
  2. 可重用/多段:封裝 Timer/Profiler 類別。
  3. 高精度/單調時鐘:PHP 7.3+ 用 hrtime(true)。
  4. 完整 Profiling:使用專業工具 (Xdebug/Blackfire)。
copyright © 萬盛學電腦網 all rights reserved