如果与Switch Speed相对

问题描述 投票:108回答:7

由于编译器优化,Switch语句通常比等效的if-else-if语句(例如,在此qazxsw poi中描述的)更快。

这种优化实际上如何运作?有没有人有一个很好的解释?

c# performance switch-statement if-statement
7个回答
177
投票

编译器可以在适用的地方构建跳转表。例如,当您使用反射器查看生成的代码时,您将看到对于字符串上的大型开关,编译器实际上将生成使用哈希表来分派这些代码的代码。哈希表使用字符串作为键,并将article代码委托为值。

这比许多链接的case测试具有渐近更好的运行时间,并且即使对于相对较少的字符串实际上更快。


14
投票

这是一个轻微的简化,因为通常任何遇到if序列的现代编译器都可以由人轻易地转换为switch语句,编译器也是如此。但是为了增加额外的乐趣,编译器不受语法的限制,因此可以在内部生成具有混合范围,单个目标等的“切换”语句 - 并且它们可以(并且确实)为交换机和if执行此操作。 .else声明。

Anyhoo,对Konrad的答案的扩展是编译器可能会生成一个跳转表,但这不一定得到保证(也不是可取的)。由于各种原因,跳转表会对现代处理器上的分支预测器做坏事,而表本身也会对缓存行为做坏事,例如。

if..else if ..

如果编译器实际上为此生成了一个跳转表,那么替换switch(a) { case 0: ...; break; case 1: ...; break; } 样式代码可能会慢一些,因为跳转表会破坏分支预测。


4
投票

不匹配的统计数据可能不太好。

如果您实际下载了源,则在if和switch情况下,已知无匹配值为21。编译器应该能够抽象出来,知道应该始终运行哪个语句,并且CPU应该能够正确地进行分支预测。

更有趣的情况是,在我看来,并非每个案例都会破裂,但这可能不是实验的范围。


4
投票

切换/ 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结构?


0
投票

if over case的唯一优点是当第一种情况的出现频率明显增加时。

不确定阈值的确切位置,但我使用case语法,除非第一个“几乎总是”通过第一个测试。

© www.soinside.com 2019 - 2024. All rights reserved.