You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

短路求值理论上快于按位求值,实际却相反,原因何在?

为什么短路逻辑运算符(&&)实际性能没比按位逻辑运算符(&)快?

嘿,这个问题戳中了很多开发者的认知误区——按道理短路求值能跳过不必要的判断,应该更快才对,但实际测试却没看出差异,甚至有时候表现差不多?咱们来拆解背后的几个关键原因:

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

火山引擎 最新活动