PHP代码执行时间测量出现负值,如何排查原因?
为什么你的PHP Profiler函数会返回负值?
嘿,这个问题我之前排查过,咱们来唠唠背后的原因和解决办法!
核心原因:忽略了秒数的进位
你当前的实现只提取了microtime()返回字符串里的微秒部分,完全没用到秒数部分。举个具体的例子:
- 开始时间:
microtime()返回"0.999999 1690000000"(微秒部分是0.999999,秒数是1690000000) - 结束时间:
microtime()返回"0.000001 1690000001"(微秒部分是0.000001,秒数是1690000001)
这时候你计算的是:0.000001 * 1e6 - 0.999999 * 1e6 = 1 - 999999 = -999998,自然得到负值。本质是被测代码的执行刚好跨了秒的边界,你只算了微秒差,没考虑秒数增加了1(也就是100万微秒)。
另外,拆分字符串的方式也有潜在风险:如果microtime()的输出有多余空格(虽然PHP官方文档里是单空格分隔,但极端情况可能有变化),explode(" ", $raw_start_time)[0]可能拿到错误的值。
修复方案:用microtime(true)直接获取带小数的时间戳
PHP的microtime(true)会直接返回一个浮点数,表示当前时间的秒数(包含微秒精度),比如1690000000.999999。用这个值来计算时间差,就完全不用自己拆分字符串,也不会漏掉秒数的变化:
function profiler($funct) { $start_time = microtime(true); $funct(); $end_time = microtime(true); // 转换为微秒返回,和你原来的输出格式一致 return ($end_time - $start_time) * 1000000; }
这个版本不仅解决了负值问题,代码也更简洁可靠。
额外优化建议
- 多次执行取平均值:单次执行的耗时可能受系统负载影响波动很大,建议让被测代码执行多次,取平均耗时:
function profiler($funct, $iterations = 1000) { $start_time = microtime(true); for ($i = 0; $i < $iterations; $i++) { $funct(); } $end_time = microtime(true); return (($end_time - $start_time) * 1000000) / $iterations; }
- 用
hrtime()获取更高精度的时间:PHP 7.3+支持hrtime(),它返回的是系统的高分辨率时间,不受系统时间调整(比如NTP同步)的影响,精度更高:
function profiler($funct) { $start = hrtime(true); // 返回纳秒数 $funct(); $end = hrtime(true); return ($end - $start) / 1000; // 转换为微秒返回 }
内容的提问来源于stack exchange,提问作者Udochukwu Enwerem
相关产品推荐
相关产品推荐

