应使用 system.nanotime() 计算时间占比,因其纳秒级精度、不受系统时钟调整影响,适合在同一上下文内对比目标逻辑与总耗时;需预热jvm、多次采样取平均,并保留2~3位有效数字。

直接用 System.currentTimeMillis() 测时间占比不合适,它精度低(毫秒级)、受系统时钟调整影响,且无法反映 CPU 真实开销。要算“一段逻辑的时间占比”,关键不是测绝对耗时,而是测它在总执行时间中占多少比例——这需要在同一上下文、相同精度、稳定时钟源下对比。
用纳秒级高精度计时
Java 提供 System.nanoTime(),基于单调递增的物理时钟(如 CPU cycle),不受系统时间跳变影响,精度达纳秒(实际约几十纳秒),适合做相对耗时测量和占比计算。
- 开始前调用一次
long start = System.nanoTime(); - 逻辑执行完立即再调一次
long end = System.nanoTime(); - 耗时 =
end - start(单位:纳秒)
明确“占比”的参照系
时间占比 = (目标逻辑耗时)÷(总耗时)。必须确保两个耗时用同一方法、同一精度测量,且覆盖完整可比区间:
- 比如整个方法执行耗时为
totalNanos,其中某段 for 循环耗时为loopNanos,则占比 ≈(double) loopNanos / totalNanos - 避免混用
currentTimeMillis和nanoTime;也别把 I/O 等阻塞操作和纯计算逻辑强行放一起算“占比”,它们性质不同
注意 JVM 预热与多次采样
刚启动时 JIT 尚未优化,单次测量偏差大。真实占比需在预热后多次运行取稳定值:
- 先循环执行几十次让 JIT 编译完成(不计入统计)
- 再连续执行 10~100 次,记录每次目标逻辑和总耗时,分别求平均值再算占比
- 也可用 JMH(Java Microbenchmark Harness)自动化处理预热、采样、统计
别忽略误差和可观测性限制
System.nanoTime() 虽好,但仍有微小误差(如调用开销、上下文切换干扰)。占比结果建议保留 2~3 位有效数字即可,例如 12.3% 或 0.123,不必显示 12.345678%:
- 两次
nanoTime()调用本身耗时约 10–100 纳秒,若逻辑本身只跑几百纳秒,占比就不可靠 - 真正想优化性能,应结合 VisualVM、JFR 或 async-profiler 查看热点方法、GC、锁竞争等深层原因,而非只盯单一占比数字
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











