【发布时间】:2021-02-23 16:28:27
【问题描述】:
级联 if-else 语句之间是否存在性能差异,例如
if (i > c20) {
// ...
} else if (i > c19) {
// ...
} else if (i > c18) {
// ...
} else if (i > c17) {
// ...
} else if (i > c16) {
// ...
} else if (i > c15) {
// ...
} else if (i > c14) {
// ...
} else if (i > c13) {
// ...
} else if (i > c12) {
// ...
} else if (i > c11) {
// ...
} else if (i > c10) {
// ...
} else if (i > c9) {
// ...
} else if (i > c8) {
// ...
} else if (i > c7) {
// ...
} else if (i > c6) {
// ...
} else if (i > c5) {
// ...
} else if (i > c4) {
// ...
} else if (i > c3) {
// ...
} else if (i > c2) {
// ...
} else if (i > c1) {
// ...
} else if (i > c0) {
// ...
} else {
// ...
}
和嵌套的 if 语句,如:
if (i > c10) {
if (i > c15) {
if (i > c18) {
if (i > c19) {
if (i > c20) {
// ...
} else {
// ...
}
} else {
//...
}
} else {
if (i > c17) {
// ...
} else {
// ...
}
}
} else {
if (i > c13) {
if (i > c14) {
// ...
} else {
// ...
}
} else {
if (i > c12) {
// ...
} else {
// ...
}
}
}
} else {
if (i > c5) {
if (i > c8) {
if (i > c9) {
//...
} else {
//...
}
} else {
if (i > c7) {
// ...
} else {
// ...
}
}
} else {
if (i > c3) {
if (i > c4) {
// ...
} else {
// ...
}
} else {
if (i > c2) {
// ...
} else {
if (i > c0) {
if (i > c1) {
// ...
}
} else {
// ...
}
}
}
}
}
如果存在差异,一个比另一个快的原因是什么?一种形式能否带来:更好的 JIT 编译、更好的缓存策略、更好的分支预测、更好的编译器优化等?我对Java 中的性能特别感兴趣,但我想知道它在 C/C++、C# 等其他语言中可能与谁相似或不同。
i 的不同分布、检查的范围和/或不同数量的if 语句将如何影响结果?
这里的值c0 到c20 是严格递增的顺序,因此引起了愤怒。例如:
c0 = 0;
c1 = 10;
c2 = 20;
c3 = 30;
c4 = 40;
c5 = 50;
c6 = 60;
c7 = 70;
c8 = 80;
c9 = 90;
c10 = 100;
c11 = 110;
c12 = 120;
c13 = 130;
c14 = 140;
c15 = 150;
c16 = 160;
c17 = 170;
c18 = 180;
c19 = 190;
c20 = 200;
或
c0 = 0;
c1 = 1;
c2 = 2;
c3 = 3;
c4 = 4;
c5 = 5;
c6 = 6;
c7 = 7;
c8 = 8;
c9 = 9;
c10 = 10;
c11 = 11;
c12 = 12;
c13 = 13;
c14 = 14;
c15 = 15;
c16 = 16;
c17 = 17;
c18 = 18;
c19 = 19;
c20 = 20;
【问题讨论】:
-
嗯,第一个是线性时间
O(n)检查(您运行 if 语句直到nth 结果)。第二个实际上更类似于O(log n)算法,因为您实际上是在拆分可能值的范围以在每个 if 分支上检查,因此意味着第二个会更快。总而言之,数组索引或哈希图仍然会超过这两种解决方案(接近O(1)),并且在此过程中的写入时间要短得多 -
分支预测、缓存、推测执行等使得在这里预测任何东西基本上是不可能和不合理的。
-
我认为你的例子是错误的:
if(i>0)为假使所有其余的i>1..n条件也为假。如果它是真的,那么else条件根本不会被检查。所以你的第一个例子完全等同于if(i>0) ...;,没有其他条件,因为它们都是第一个条件的子集(只有当它为真时才能为真)。 -
@PeterCordes 感谢您指出错误。我更正了。
标签: java if-statement control-flow branch-prediction