测微秒级耗时必须用system.nanotime(),因其仅测间隔、精度达纳秒级,而currenttimemillis()粒度粗(毫秒级)易得0;正确做法是两次nanotime()相减后整除1000转微秒,避免混用、单次测量或误作时间戳。

测微秒级耗时,必须用 System.nanoTime(),而不是 currentTimeMillis()。它不表示“现在几点”,只回答“这段代码跑了多久”,且精度足够分辨微秒差异。
适合微秒级测量的典型场景
高频交易订单处理、游戏物理帧计算、音视频解码延迟、RPC调用链路打点、算法微基准对比——这些场景中,真实耗时常在几微秒到几百微秒之间。currentTimeMillis() 因系统时钟粒度限制(Windows 常为 10–16ms,Linux/macOS 也多在毫秒级),两次调用很可能返回相同值,结果恒为 0;而 nanoTime() 在主流系统上实际分辨率可达纳秒至百纳秒级,能稳定捕捉微秒变化。
正确获取微秒值的操作要点
- 调用两次
System.nanoTime(),相减得纳秒差:long nanos = end - start - 转微秒用整数除法:
long micros = nanos / 1000(向下取整,单位是微秒) - 不要用
currentTimeMillis()替代,也不要用nanos / 1000.0强转 double 再四舍五入——除非你明确需要小数精度,否则整数截断更符合微秒级统计惯例 - 避免在日志打印、对象创建、GC 易触发路径中直接测量,防止干扰结果
容易踩坑的错误用法
- 把
nanoTime()值当时间戳存库或传给定时器(如ScheduledExecutorService),它没有绝对时间意义 - 跨 JVM 实例比较两个
nanoTime()值,起点不同,数值不可比 - 拿
nanoTime()和currentTimeMillis()直接相减或混算,单位和起点都不同,结果无意义 - 单次测量就下结论:JIT 预热、CPU 频率波动、线程调度都会影响首次运行,应批量采样并丢弃前若干轮
提升测量可信度的实用建议
- 预热至少 10000 次被测逻辑,再开始正式采集
- 将计算结果赋给
volatile变量(如volatile int sink),防止 JIT 优化掉整个代码块 - 单线程内完成 start/end 记录,避免上下文切换引入噪声
- 压测时关注 P95/P99 延迟,而非平均值——尾部延迟更能暴露锁竞争或 GC 暂停问题
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











