短路求值理论上快于按位求值,实际却相反,原因何在?
为什么短路逻辑运算符(&&)实际性能没比按位逻辑运算符(&)快?
嘿,这个问题戳中了很多开发者的认知误区——按道理短路求值能跳过不必要的判断,应该更快才对,但实际测试却没看出差异,甚至有时候表现差不多?咱们来拆解背后的几个关键原因:
1. JVM即时编译(JIT)的“抹平”效应
Java的JVM可不是吃素的,运行时会对代码做各种激进优化。如果你的测试逻辑足够简单(比如固定的布尔值、无复杂依赖的判断),JIT可能直接把整个逻辑表达式的结果提前计算出来,不管你用&&还是&,最终生成的机器码可能完全一致。极端情况下,JIT甚至会把那些对程序结果没影响的冗余逻辑直接删掉,你测的根本不是真正的运算耗时。
2. 测试场景的开销掩盖了差异
你提供的代码里用了控制台输入Scanner来获取布尔值,这可是个大坑!IO操作的耗时(等待用户输入、控制台输出)是以毫秒甚至秒为单位的,而逻辑运算本身只需要几个CPU周期(纳秒级)。这点细微的性能差,完全被IO的开销给淹没了,根本测不出来。
要做有效的性能对比,得写纯计算的、高循环次数的测试——比如循环个几十亿次,放大差异才能看出来。
3. 短路求值的优势只在特定场景生效
短路&&的优势是当第一个条件为false时,直接跳过第二个条件的判断。但如果你的测试用例里,第一个条件大多为true,那&&和&的执行逻辑其实是一样的:都要判断两个条件,自然性能没差别。只有当第一个条件经常为false时,&&的优势才会显现出来。
给你一个靠谱的测试示例
试试这段代码,调整a的值(true/false),就能看到明显差异:
public class ShortCircuitVsBitwiseTest { public static void main(String[] args) { boolean a = false; // 改成true再测一次,对比差异 boolean b = true; long iterations = 1000000000L; long startTime, endTime; // 预热JVM(让JIT完成优化) for (long i = 0; i < iterations / 10; i++) { a && b; a & b; } // 测试短路&& startTime = System.nanoTime(); for (long i = 0; i < iterations; i++) { boolean result = a && b; } endTime = System.nanoTime(); System.out.println("短路&& 耗时: " + (endTime - startTime) + " 纳秒"); // 测试按位& startTime = System.nanoTime(); for (long i = 0; i < iterations; i++) { boolean result = a & b; } endTime = System.nanoTime(); System.out.println("按位& 耗时: " + (endTime - startTime) + " 纳秒"); } }
当a为false时,&&的耗时会比&少很多——因为它根本不会去判断b;但如果a为true,两者的耗时几乎没差别。
最后提醒
性能测试一定要注意:
- 先预热JVM,避免第一次循环的编译开销影响结果
- 多次测试取平均值,减少系统波动的干扰
- 尽量隔离其他开销(比如IO、对象创建),只测你关心的逻辑
内容的提问来源于stack exchange,提问作者Shant Dashjian




