system.nanotime()是最精准的java代码执行时间测量方法,因其基于高精度硬件计时器、单调递增且不受系统时钟调整影响;需成对调用、仅做差值运算、避免跨线程复用和高频单次测量,并配合jit预热;适用于快速验证,严谨微基准测试应使用jmh。

测量Java代码执行时间,System.nanoTime() 是最精准的选择,尤其适合微基准测试或性能敏感场景。
为什么用 System.nanoTime() 而不是 System.currentTimeMillis()
System.currentTimeMillis() 返回的是自1970年1月1日以来的毫秒数,受系统时钟调整(如NTP校时)影响,可能产生跳变或负值,不适合测间隔;而 System.nanoTime() 提供的是单调递增的纳秒级计时器,基于高精度硬件计时器(如TSC),不受系统时间修改干扰,分辨率通常在纳秒级(实际取决于JVM和底层平台),专为测量耗时设计。
正确使用方式:成对调用 + 避免常见陷阱
必须在同一上下文中成对调用,且避免将结果用于时间点计算(它不代表真实时间)。关键注意事项:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 只做差值运算:
long start = System.nanoTime(); /* 业务代码 */; long elapsed = System.nanoTime() - start; - 不要跨线程复用起始值——每个线程应独立记录自己的开始时间
- 避免在循环内反复调用
System.nanoTime()测单次极短操作,其自身开销(几十纳秒)可能干扰结果;高频小操作建议批量执行后取平均 - 注意JIT编译影响:首次运行可能包含类加载、JIT优化等额外开销,正式测量前应预热(如空跑若干次)
简单可靠的测量模板
适用于方法级或代码块耗时统计:
long startTime = System.nanoTime();
// 你要测量的代码,例如:doSomething();
long durationNs = System.nanoTime() - startTime;
double durationMs = durationNs / 1_000_000.0;
System.out.printf("耗时:%.3f ms%n", durationMs);
若需多次运行取平均,可封装为工具方法,但注意排除JIT预热阶段的数据。
与 JMH 的关系:何时该升级工具
System.nanoTime() 适合快速验证、调试或粗粒度观测。但若要做严谨的性能对比(比如不同算法、JVM参数影响),手动测量易受JIT、GC、CPU频率变化等干扰。此时应使用 JMH(Java Microbenchmark Harness) ——它自动处理预热、Fork、统计校验等,结果更可信。可以把 System.nanoTime() 当作“手电筒”,JMH 则是“显微镜”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










