HRTime 高精度计时
PHP 8.1 引入了 HRTime(High Resolution Time)扩展,提供了纳秒级的高精度时间测量功能。相比 microtime(true) 的微秒精度,HRTime 可以测量更小的时间间隔,特别适合性能分析和基准测试。
前置知识
阅读本节前,建议先了解:DateTime 类
基础概念
HRTime 的优势
| 函数 | 精度 | 说明 |
|---|---|---|
time() | 秒 | Unix 时间戳 |
microtime(true) | 微秒 (1e-6) | 浮点秒数 |
hrtime(true) | 纳秒 (1e-9) | 高精度整数 |
安装
HRTime 从 PHP 8.1 开始成为核心扩展,默认启用,无需额外安装。
hrtime() 函数
基本用法
php
<?php
declare(strict_types=1);
// hrtime() 返回纳秒级时间
$nanoseconds = hrtime(true);
echo "纳秒时间戳: {$nanoseconds}" . PHP_EOL;
// 转换为秒
$seconds = $nanoseconds / 1_000_000_000;
echo "秒: {$seconds}" . PHP_EOL;
// 转换为毫秒
$milliseconds = $nanoseconds / 1_000_000;
echo "毫秒: {$milliseconds}" . PHP_EOL;
// 返回数组形式 [秒, 纳秒]
$parts = hrtime(false);
echo "秒: {$parts[0]}, 纳秒: {$parts[1]}" . PHP_EOL;性能测量
php
<?php
declare(strict_types=1);
/**
* 使用 hrtime 测量代码执行时间
*/
function benchmark(callable $fn, int $iterations = 1000): array
{
$totalNs = 0;
$times = [];
for ($i = 0; $i < $iterations; $i++) {
$start = hrtime(true);
$fn();
$end = hrtime(true);
$elapsed = $end - $start;
$totalNs += $elapsed;
$times[] = $elapsed;
}
sort($times);
return [
'total_ms' => $totalNs / 1_000_000,
'avg_ns' => (int) ($totalNs / $iterations),
'min_ns' => $times[0],
'max_ns' => $times[count($times) - 1],
'p50_ns' => $times[(int) (count($times) * 0.50)],
'p95_ns' => $times[(int) (count($times) * 0.95)],
'p99_ns' => $times[(int) (count($times) * 0.99)],
'iterations' => $iterations,
];
}
// 测试 json_encode 性能
$data = array_fill(0, 1000, ['id' => 1, 'name' => '张三', 'active' => true]);
$result = benchmark(fn() => json_encode($data), 1000);
echo "json_encode 基准测试:" . PHP_EOL;
echo "总耗时: {$result['total_ms']} ms" . PHP_EOL;
echo "平均: {$result['avg_ns']} ns" . PHP_EOL;
echo "P50: {$result['p50_ns']} ns" . PHP_EOL;
echo "P95: {$result['p95_ns']} ns" . PHP_EOL;
echo "P99: {$result['p99_ns']} ns" . PHP_EOL;与 microtime 对比
php
<?php
declare(strict_types=1);
// microtime(true) 精度有限
$before = microtime(true);
usleep(100); // 100 微秒
$after = microtime(true);
echo "microtime 差值: " . (($after - $before) * 1_000_000) . " us" . PHP_EOL;
// hrtime(true) 精度更高
$before = hrtime(true);
usleep(100);
$after = hrtime(true);
echo "hrtime 差值: " . ($after - $before) . " ns" . PHP_EOL;实战示例
请求耗时追踪
php
<?php
declare(strict_types=1);
class PerformanceTracker
{
private array $timers = [];
private int $requestStart;
public function __construct()
{
$this->requestStart = hrtime(true);
}
public function start(string $name): void
{
$this->timers[$name] = ['start' => hrtime(true), 'end' => null];
}
public function end(string $name): float
{
if (!isset($this->timers[$name])) {
throw new RuntimeException("计时器不存在: {$name}");
}
$this->timers[$name]['end'] = hrtime(true);
$elapsed = $this->timers[$name]['end'] - $this->timers[$name]['start'];
return $elapsed / 1_000_000; // 转为毫秒
}
public function getReport(): array
{
$report = [];
foreach ($this->timers as $name => $timer) {
$report[$name] = $timer['end'] !== null
? ($timer['end'] - $timer['start']) / 1_000_000
: null;
}
$total = (hrtime(true) - $this->requestStart) / 1_000_000;
$report['_total'] = $total;
return $report;
}
}
// 使用示例
$tracker = new PerformanceTracker();
$tracker->start('database');
// ... 数据库查询 ...
$dbTime = $tracker->end('database');
$tracker->start('api_call');
// ... API 调用 ...
$apiTime = $tracker->end('api_call');
$report = $tracker->getReport();
echo "数据库: {$report['database']} ms" . PHP_EOL;
echo "API: {$report['api_call']} ms" . PHP_EOL;
echo "总耗时: {$report['_total']} ms" . PHP_EOL;注意事项
hrtime(true)返回的值是单调递增的,不受系统时间调整影响hrtime()不适合用于获取当前日期时间,仅用于时间间隔测量- 对于一般场景,
microtime(true)足够使用
下一节
继续学习:GD 图像处理