在效能優化過程中,精確測量特定函數的執行時間至關重要。本文提供一個可重複使用的 EfficiencyTester 類,支援多次測試取平均值,並可切換秒/微秒精度。
<?php
/**
* class EfficiencyTester
* 效能測試器,測試函數的執行時間
* @version 1.0
* @author Kross
*/
class EfficiencyTester {
/** 測試次數 */
private $testTimes = 1000;
/**
* 根據模式獲取時間戳
* @param string $timeModel 時間模式:'MS' 微秒(預設)、'S' 秒
* @return float 時間戳
*/
private function getTime($timeModel = 'MS') {
if ($timeModel === 'MS') {
return microtime(true); // 回傳浮點數微秒時間
} elseif ($timeModel === 'S') {
return time(); // 回傳秒級時間戳
}
return microtime(true);
}
/**
* 測試目標函數單次執行時間
* @param callable $functionName 目標函數(可為匿名函數、陣列呼叫格式)
* @param string $timeModel 時間模式
* @return float 單次執行耗時
*/
public function testOnce($functionName, $timeModel = 'MS') {
$start = $this->getTime($timeModel);
$functionName(); // 執行目標函數
$end = $this->getTime($timeModel);
return $end - $start;
}
/**
* 多次測試取平均值
* @param callable $functionName 目標函數
* @param string $timeModel 時間模式
* @return float 平均執行時間
*/
public function test($functionName, $timeModel = 'MS') {
$total = 0;
for ($i = 1; $i <= $this->testTimes; $i++) {
$total += $this->testOnce($functionName, $timeModel);
}
return $total / $this->testTimes;
}
/** 設定測試次數 */
public function setTestTimes($times) {
$this->testTimes = max(1, (int)$times);
}
}
<?php
require_once 'EfficiencyTester.class.php';
$tester = new EfficiencyTester();
// 測試內建函數 rand() 平均執行時間(微秒)
echo "rand() 平均耗時: " . $tester->test('rand') . " 秒\n";
// 測試自訂函數
$tester->setTestTimes(5000); // 增加測試次數提高精度
$avgTime = $tester->test(function() {
// 模擬某業務邏輯
$arr = range(1, 100);
shuffle($arr);
return array_sum($arr);
});
echo "自訂邏輯平均耗時: " . $avgTime . " 秒\n";
// 以秒為單位測試(適用於耗時較長的操作)
$tester->setTestTimes(10);
$longOp = $tester->test(function() {
sleep(1); // 模擬 1 秒操作
}, 'S');
echo "長操作平均耗時: " . $longOp . " 秒\n";
microtime(true) 直接回傳浮點數,避免字串解析開銷getTime() 的判斷邏輯本身會引入微小誤差microtime(true),由呼叫端自行換算call_user_func_array)hrtime()(PHP 7.3+)獲取奈秒級精度對於更專業的效能分析,建議使用:
cachegrind 格式檔案,配合 KCacheGrind/QCacheGrind 視覺化分析