检查布尔值比在java中设置布尔值更快吗?

2022-09-03 14:16:49

这:

if (var) {
    var = false;
}

与此相比:

var = false;

有速度差吗?


答案 1

有几件事在起作用,对实际性能的最终影响是您需要针对您的用例进行衡量的。我假设这是你发现经常发生的方法:

  1. 分支预测 - 如果 var 几乎总是假的,这是代码所建议的,分支预测器几乎总是正确的。如果字段经常变化,那么这将成为一个经常被误解的分支,并且价格昂贵。

  2. 读取未命中 - 如果 var 主要是读取(并且读取了很多),那么避免无缘无故地更改可以通过不使它所在的缓存行失效来帮助您的软件。如果您写入它,则读取它(以及同一缓存行上的任何内容)的每个其他内核都需要获得一个遇到读取未命中的新副本。这意味着上述方法可能值得放慢速度,以使读取速度更加一致。

  3. 写入成本与读取成本 - 如果 var 是易失性的,那么它的写入是 LoadStore 障碍,非常昂贵。相比之下,读取易失性(LoadLoad屏障)相当便宜(对于经常使用且几乎改变的值,缓存命中)。相比之下,这可以使分支非常便宜。

这是人们所做的优化,可以在JDK(IIRC)中找到示例,我假设您有理由考虑它。


答案 2

第一个代码包含一个比较,因此您的编译器可能会生成一个java字节码,如下所示:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1      
       1: istore_1      
       2: iload_1       
       3: ifeq          8
       6: iconst_0      
       7: istore_1      
       8: return    

对于第二个代码,生成的字节码较短,因为缺少比较:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1      
       1: istore_1      
       2: iconst_0      
       3: istore_1      
       4: return      

虚拟机在第一个示例中执行 8 个命令所需的时间比在第二个示例中执行 4 个命令所需的时间更多。虽然这种差异不应该是高,但第二个代码更清楚。

将代码放在一个简单的 main 方法中并编译该类。然后运行命令提示符并更改为目录。要反汇编类,请调用 。字节码.txt将包含类的 java 字节码。java/binjavap -c path/to/YourClass.class >> path/to/bytecode.txt


推荐