if else 的顺序对性能有影响吗?例如把最有可能的条件放在前面更好

way*_*yne 6 java performance jit jvm

我正在尝试衡量顺序是否会if else影响性能。

\n

例如,如果

\n
if (condition == more likely condition) {}\nelse /** condition == rare condition **/ {}\n
Run Code Online (Sandbox Code Playgroud)\n

\n
if (condition == rare condition) {}\nelse /** condition == more likely condition **/ {}\n
Run Code Online (Sandbox Code Playgroud)\n

我想也许JIT应该能够优化它,无论我把它放在哪个顺序?但找不到任何关于此的文档。

\n

我尝试用以下基准测试自己。基于此,我没有看到强有力的证据表明该顺序很重要。bias=0.9因为如果确实如此,我认为(概率为0.9)时的吞吐量if (zeroOrOne == 1)应该高于bias=0.1else概率为0.9)时的吞吐量。

\n
public class BranchBench {\n    @Param({ "0.02", "0.1", "0.9", "0.98", })\n    private double bias;\n\n    @Param("10000")\n    private int count;\n\n    private final List<Byte> randomZeroOnes = new ArrayList<>(count);\n\n    @Setup\n    public void setup() {\n        Random r = new Random(12345);\n\n        for (int c = 0; c < count; c++) {\n            byte zeroOrOne = (byte) (c < (bias * count) ? 1 : 0);\n            randomZeroOnes.add(zeroOrOne);\n        }\n        Collections.shuffle(randomZeroOnes, r);\n    }\n\n    @Benchmark\n    public int static_ID_ifElse() {\n        int i = 0;\n        for (final Byte zeroOrOne : randomZeroOnes) {\n            if (zeroOrOne == 1) {\n                i++;\n            } else {\n                i--;\n            }\n        }\n        return i;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
Benchmark                     (bias)  (count)   Mode  Cnt    Score   Error   Units\nBranchBench.static_ID_ifElse    0.02    10000  thrpt   15  137.409 \xc2\xb1 1.376  ops/ms\nBranchBench.static_ID_ifElse     0.1    10000  thrpt   15  129.277 \xc2\xb1 1.552  ops/ms\nBranchBench.static_ID_ifElse     0.9    10000  thrpt   15  125.640 \xc2\xb1 5.858  ops/ms\nBranchBench.static_ID_ifElse    0.98    10000  thrpt   15  137.427 \xc2\xb1 2.396  ops/ms\n
Run Code Online (Sandbox Code Playgroud)\n

Nic*_*men -2

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

如今,处理器的猜测正确率超过 90%,因此任何手写的条件调整都不再那么重要。

关于分支预测的文献相当多:

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

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

  • @boneill,问题的标题可能会产生误导,实际问题不是指多个条件的顺序,而只是指是否测试一个条件或其否定。 (2认同)