System.nanoTime() 可用于纳秒级相对性能对比,需预热、防JIT优化、多次平均;但严谨微基准测试应使用JMH或字节码分析。

直接用 System.nanoTime() 做毫微秒级计时,配合足够多的循环次数,能比较出不同运算符在真实 JVM 中的相对开销。重点不是绝对数值,而是差异趋势。
用 nanoTime 粗粒度对比
Java 不提供单条指令的执行周期测量,但 System.nanoTime() 提供纳秒精度的时间戳(实际分辨率取决于系统),适合做相对性能观察。
- 每次测试前调用
System.gc()并稍作等待,减少 GC 干扰 - 先预热循环(比如跑 10 万次不计时),让 JIT 编译器完成优化
- 正式测试至少运行百万次以上,取多次平均值,避免单次抖动
- 把要测的运算单独封装成方法,避免被 JVM 内联或消除
典型对比场景示例
比如比较 !(逻辑非)和 ==(相等判断):
-
!是单目操作,只读一个 boolean 值再翻转,几乎没有计算开销 -
==是双目操作,需加载两个操作数再比对,但对基本类型仍是极快的 CPU 指令 - 实际测下来,两者耗时几乎一致,差值在几纳秒内,属于同一量级
真正拉开差距的是涉及对象、方法调用或装箱的操作,比如 obj instanceof List 对比 obj.getClass() == ArrayList.class —— 前者通常更快,尤其在接口或深层继承链中。
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
注意编译器和 JVM 的干扰
有些表达式会被 JIT 直接优化掉,导致测出来是 0 纳秒。例如:
-
int x = 5 + 3;在编译期就被算成8,运行时根本没“加法” -
boolean b = true && false;可能被常量折叠,不执行短路逻辑 - 解决办法:操作数尽量来自方法参数或数组元素,不让编译器提前推断
更可靠的替代方式:看字节码和 JMH
如果需要严谨结论,不建议手写循环测速:
- 用
javap -c查看编译后的字节码,对比指令数量和跳转复杂度 - 用 JMH(Java Microbenchmark Harness)框架,它自动处理预热、GC 控制、统计校准等问题
- JMH 能暴露分支预测失败率、缓存命中情况等底层指标,比手动 nanoTime 更可信
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










