Java测速最常用且推荐的方式是System.nanoTime(),因其纳秒级精度、单调递增、不受系统时钟调整影响,适合测量代码执行耗时;而currentTimeMillis()因挂钟特性易受NTP同步等干扰导致结果失真。

Java中测速最常用且推荐的方式就是System.nanoTime(),它提供纳秒级精度(实际取决于系统),比System.currentTimeMillis()更稳定、不受系统时钟调整影响,适合测量代码执行耗时。
为什么选 nanoTime 而不是 currentTimeMillis
System.currentTimeMillis()返回的是自1970年1月1日以来的毫秒数,本质是挂钟时间,可能因NTP同步、手动调时而跳变或回退,导致测速结果为负或严重失真。而System.nanoTime()是单调递增的“墙上时钟”,基于高精度计时器(如TSC),只用于测量时间间隔,不对应真实时刻,因此更适合性能测试。
- 精度通常在纳秒级(Linux/Windows下多数为几十纳秒分辨率)
- 不受系统时间修改影响,不会出现负值
- 开销极小,多次调用几乎无性能负担
- 适用于微基准测试(micro-benchmark),但非JMH替代方案
正确使用 nanoTime 的基本模式
核心原则:只测“差值”,不关心单次返回值含义;避免在循环内反复调用造成干扰;确保被测逻辑足够“热”(JIT预热后测量更准)。
- 记录起始时间:
long start = System.nanoTime(); - 执行待测代码(建议单独方法封装,避免JIT内联干扰)
- 记录结束时间:
long end = System.nanoTime(); - 计算耗时:
long elapsed = end - start;(单位是纳秒) - 如需毫秒:用
(double) elapsed / 1_000_000,注意类型转换防整除截断
常见陷阱与规避建议
看似简单,但实际使用中容易踩坑:
立即学习“Java免费学习笔记(深入)”;
- 不要测空循环或过短操作:低于几十纳秒的操作,误差占比大,结果不可靠;建议重复执行N次再取平均
- 避免JIT未预热就测:首次运行可能包含类加载、解释执行、JIT编译开销;应先运行若干轮“预热”,再正式采集
-
别在循环里反复调用 nanoTime:例如
for (int i=0; i<n; i++) { t += nanoTime()-start; }会把调用开销也计入,应把整个循环包在两次nanoTime之间 - 注意JVM逃逸分析和优化:如果被测对象未被使用,JIT可能直接优化掉;确保结果有副作用(如赋值给volatile变量或打印)
一个轻量实用的测速工具片段
无需引入第三方库,几行代码就能支撑日常调试:
public static long time(Runnable task) {
long start = System.nanoTime();
task.run();
return System.nanoTime() - start;
}
<p>// 使用示例
long ns = time(() -> {
int sum = 0;
for (int i = 0; i < 100000; i++) sum += i;
});
System.out.printf("耗时 %.3f ms%n", ns / 1e6);</p>若需更高可靠性(如多轮采样、排除异常值、统计标准差),建议直接使用JMH;但对快速验证、开发阶段粗略对比,System.nanoTime()配合合理写法已足够有效。


















