由于编译器优化,Switch语句通常比等效的if-else-if语句(例如,在此qazxsw poi中描述的)更快。
这种优化实际上如何运作?有没有人有一个很好的解释?
编译器可以在适用的地方构建跳转表。例如,当您使用反射器查看生成的代码时,您将看到对于字符串上的大型开关,编译器实际上将生成使用哈希表来分派这些代码的代码。哈希表使用字符串作为键,并将article代码委托为值。
这比许多链接的case
测试具有渐近更好的运行时间,并且即使对于相对较少的字符串实际上更快。
这是一个轻微的简化,因为通常任何遇到if
序列的现代编译器都可以由人轻易地转换为switch语句,编译器也是如此。但是为了增加额外的乐趣,编译器不受语法的限制,因此可以在内部生成具有混合范围,单个目标等的“切换”语句 - 并且它们可以(并且确实)为交换机和if执行此操作。 .else声明。
Anyhoo,对Konrad的答案的扩展是编译器可能会生成一个跳转表,但这不一定得到保证(也不是可取的)。由于各种原因,跳转表会对现代处理器上的分支预测器做坏事,而表本身也会对缓存行为做坏事,例如。
if..else if ..
如果编译器实际上为此生成了一个跳转表,那么替换switch(a) { case 0: ...; break; case 1: ...; break; }
样式代码可能会慢一些,因为跳转表会破坏分支预测。
不匹配的统计数据可能不太好。
如果您实际下载了源,则在if和switch情况下,已知无匹配值为21。编译器应该能够抽象出来,知道应该始终运行哪个语句,并且CPU应该能够正确地进行分支预测。
更有趣的情况是,在我看来,并非每个案例都会破裂,但这可能不是实验的范围。
切换/ case语句通常可以更快1级,但是当你开始进入2级或更多时,switch / case语句的开始时间是嵌套if / else语句的2-3倍。
if..else if..
突出显示嵌套此类语句时的速度差异。
例如,根据他们的测试,示例代码如下:
This article has some speed comparisons
在等效的switch / case语句运行的一半时间内完成:
if (x % 3 == 0)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 1)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 2)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
是的,这是一个基本的例子,但它说明了这一点。
因此,对于只有一层深度的简单类型,可能会使用switch / case作为结论,但对于更复杂的比较和多个嵌套级别,使用经典的if / else结构?
if over case的唯一优点是当第一种情况的出现频率明显增加时。
不确定阈值的确切位置,但我使用case语法,除非第一个“几乎总是”通过第一个测试。