我试图衡量if else的顺序是否会影响性能.

例如,如果

if (condition == more likely condition) {}
else /** condition == rare condition **/ {}

快于

if (condition == rare condition) {}
else /** condition == more likely condition **/ {}

我认为,也许JIT应该能够优化它,无论我把它的顺序?但找不到任何有关此的文档.

我试着用以下基准测试自己.基于这一点,我没有看到强有力的证据表明顺序很重要.因为如果是这样,我认为当bias=0.9(if (zeroOrOne == 1)的概率为真是0.9)时的吞吐量应该高于当bias=0.1(else的概率为0.9)时的吞吐量.

public class BranchBench {
    @Param({ "0.02", "0.1", "0.9", "0.98", })
    private double bias;

    @Param("10000")
    private int count;

    private final List<Byte> randomZeroOnes = new ArrayList<>(count);

    @Setup
    public void setup() {
        Random r = new Random(12345);

        for (int c = 0; c < count; c++) {
            byte zeroOrOne = (byte) (c < (bias * count) ? 1 : 0);
            randomZeroOnes.add(zeroOrOne);
        }
        Collections.shuffle(randomZeroOnes, r);
    }

    @Benchmark
    public int static_ID_ifElse() {
        int i = 0;
        for (final Byte zeroOrOne : randomZeroOnes) {
            if (zeroOrOne == 1) {
                i++;
            } else {
                i--;
            }
        }
        return i;
    }
}
Benchmark                     (bias)  (count)   Mode  Cnt    Score   Error   Units
BranchBench.static_ID_ifElse    0.02    10000  thrpt   15  137.409 ± 1.376  ops/ms
BranchBench.static_ID_ifElse     0.1    10000  thrpt   15  129.277 ± 1.552  ops/ms
BranchBench.static_ID_ifElse     0.9    10000  thrpt   15  125.640 ± 5.858  ops/ms
BranchBench.static_ID_ifElse    0.98    10000  thrpt   15  137.427 ± 2.396  ops/ms

推荐答案

在现代处理器上,我认为条件的顺序不再那么重要了.作为指令管道的一部分,处理器将执行所谓的branch prediction;它猜测哪个条件为真,并将指令预加载到管道中.

如今,处理器猜对了>;90%的情况下,任何手写的条件调整都不那么重要.

关于分支预测有很多文献:

https://dzone.com/articles/branch-prediction-in-java

https://www.baeldung.com/java-branch-prediction

Java相关问答推荐

如何粘合(合并)文件Lucene?

使用JdkClientHttpRequestFactory通过Spring RestClient和Wiemock读取时达到EOF

根据对象和值的参数将映射<;T、值&>转换为列表<;T&>

Spring Boot Maven包

Spring Data JPA慢慢地创建了太多非活动会话

如何在Cosmos DB(Java SDK)中增加默认响应大小

将关闭拍卖的TimerService

Dijkstra搜索算法的实现

当我在Java中有一个Synchronized块来递增int时,必须声明一个变量Volatile吗?

有没有办法知道在合并中执行了什么操作?

IntelliJ IDEA中的JavaFX应用程序无法在资源中找到CSS文件

为什么mvn编译生命周期阶段不只是编译已更改的java文件?

具有多个分析模式的复杂分隔字符串的正则表达式

如何修复Spring Boot应用程序中的RestDocumentationGenerationException:java.io.FileNotFoundException:/curl-request.adoc(只读文件系统)?

如何在Selenium上继续使用最新的WebDriver版本

如何使用stream.allMatch()为空流返回false?

使用DynamoDB增强客户端时未更新属性

在对象列表上调用提取后,如何判断没有值为空?

JavaFX 不嵌入谷歌 map html

Quarkus:当请求包含 Bearer 令牌时,允许的路由为 401