在互斥条件下,多个“ if”语句与“ if else if”之间的性能差异吗?

Jec*_*eck 9 java optimization

我很好奇Java如何对具有互斥条件的多个“ if”语句进行优化,但是我不具备自己分析该知识的知识。问题基本上是该问题的Java版本。“ if if”与“ if else if”的性能差异

我已经看到针对的if语句回答了return这个问题,但是这个问题是针对if具有互斥条件但不返回的语句。

1.多个if语句

if (x == 0) doSomething();
if (x == 2) doSomething();
if (x == 5) doSomething();
Run Code Online (Sandbox Code Playgroud)

2.链接的If-else语句

if (x == 0) doSomething();
else if (x == 2) doSomething();
else if (x == 5) doSomething();
Run Code Online (Sandbox Code Playgroud)

问题
#1和#2是否执行相同的编译后?
(另外:如果是这样,那么Java可以优化条件的复杂程度有多大?)

Dan*_*ams 4

没有什么比老式的计时测试更好的了:

long total = 0;
long startTime;
long endTime;

for (int j = 0; j < 10; j++) {
    startTime = System.currentTimeMillis();

    for (int i = 0; i < 100000000; i++) {
        if (i % 3 == 0) total += 1;
        if (i % 3 == 1) total += 2;
        if (i % 3 == 2) total += 3;
    }

    endTime = System.currentTimeMillis();
    System.out.println("If only: " + (endTime - startTime));

    startTime = System.currentTimeMillis();

    for (int i = 0; i < 100000000; i++) {
        if (i % 3 == 0) total += 1;
        else if (i % 3 == 1) total += 2;
        else if (i % 3 == 2) total += 3;
    }

    endTime = System.currentTimeMillis();
    System.out.println("If-else: " + (endTime - startTime));
}
System.out.println(total);
Run Code Online (Sandbox Code Playgroud)

(“总计”值对于防止编译器删除整个循环是必要的!)

输出:

If only: 215
If-else: 137
If only: 214
If-else: 121
If only: 210
If-else: 120
If only: 211
If-else: 120
If only: 211
If-else: 121
If only: 210
If-else: 121
If only: 210
If-else: 121
If only: 211
If-else: 120
If only: 211
If-else: 120
If only: 211
If-else: 121
3999999980
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,即使 if 条件明显是互斥的,if-else 块的运行速度也明显更快。由于两个循环所需的时间长度不同,因此每个循环的编译代码必须不同。显然编译器没有对此进行优化。JIT 或 CPU 分支预测也不完全如此。仍然存在实质性差异。

我的建议:尽可能使用 If-else

编辑:我还尝试交换两个循环并得到相同的结果。if-else if 更快。

编辑2:我在整个测试中添加了一个for循环,以消除初始化或预热中的任何差异。结果是一样的。