397

我是前 Pascal 人,目前正在学习 C#。我的问题如下:

下面的代码是否比进行切换更快?

int a = 5;

if (a == 1)
{
    ....
}
else if(a == 2)
{
    ....
}
else if(a == 3)
{
    ....
}
else if(a == 4)
{
    ....
}
else
    ....

和开关:

int a = 5;

switch(a)
{
    case 1:
        ...
        break;

    case 2:
        ...
        break;

    case 3:
        ...
        break;

    case 4:
        ...
        break;

    default:
        ...
        break;


}

哪个更快?

我在问,因为我的程序具有类似的结构(很多很多“else if”语句)。我应该把它们变成开关吗?

4

14 回答 14

705

对于少数几项,差异很小。如果您有很多物品,您绝对应该使用开关。

如果一个开关包含五个以上的项目,则使用查找表或哈希列表来实现。这意味着所有项目都获得相同的访问时间,与 if:s 列表相比,最后一个项目需要更多时间才能到达,因为它必须首先评估每个先前的条件。

于 2009-04-20T11:14:15.947 回答
184

你为什么在乎?

99.99% 的时间,你不应该在意。

这些类型的微优化不太可能影响代码的性能。

此外,如果您需要关心,那么您应该对您的代码进行性能分析。在这种情况下,找出 switch case 和 if-else 块之间的性能差异将是微不足道的。

编辑:为了清楚起见:实施更清晰和更可维护的设计。通常,当遇到巨大的 switch-case 或 if-else 块时,解决方案是使用多态性。找到正在改变的行为并将其封装起来。我以前不得不处理像这样巨大、丑陋的 switch case 代码,而且通常简化起来并不难。但是哦,太令人满意了。

于 2009-04-20T11:27:23.840 回答
32

相信这个性能评估,switch case 更快。

这是结论:

结果表明 switch 语句比 if-else-if 梯形图执行得更快。这是由于编译器能够优化 switch 语句。在 if-else-if 梯形图的情况下,代码必须按照程序员确定的顺序处理每个 if 语句。但是,因为 switch 语句中的每个 case 都不依赖于较早的 case,所以编译器能够以提供最快执行速度的方式重新排序测试。

于 2009-04-20T11:11:19.200 回答
16

另一件需要考虑的事情:这真的是您的应用程序的瓶颈吗?在极少数情况下确实需要这种优化。大多数时候,你可以通过重新思考你的算法和数据结构来获得更好的加速。

于 2009-04-20T11:18:41.303 回答
11

Switch 通常比长长的 if 列表要快,因为编译器可以生成跳转表。列表越长,switch 语句对一系列 if 语句的影响就越好。

于 2009-04-20T11:11:16.640 回答
10

我会说切换是要走的路,它既更快又更好的做法。

这是一个链接,显示了比较两者的基准测试。

于 2009-04-20T11:10:56.453 回答
7

应该不难测试,创建一个在 5 个数字之间切换或 ifelse 的函数,将 rand(1,5) 放入该函数并在计时时循环几次。

于 2009-04-20T11:10:07.190 回答
6

switch如果可能,通常由编译器翻译成查找表。因此,查找任意案例是 O(1),而不是在找到您想要的案例之前实际进行一些案例比较。

所以在很多情况下一个if/else if链会比较慢。不过,根据您的案件受到打击的频率,这可能没有什么区别。

于 2009-04-20T11:13:27.337 回答
5

从技术上讲,它们产生完全相同的结果,因此它们应该以几乎相同的方式进行优化。但是,与 ifs 相比,编译器使用跳转表优化 switch case 的可能性更大。

我在这里谈论一般情况。对于 5 个条目,假设您按频率对条件进行排序,为 if 执行的平均测试次数应少于 2.5。除非在一个非常紧凑的循环中,否则几乎不会成为写回家的瓶颈。

于 2009-04-20T11:10:52.087 回答
5

比 switch 的性能优势(相对轻微,但值得注意)更重要的是可读性问题。

与 if 链相比,我发现一个 switch 语句的意图和纯空格非常清晰。

于 2009-04-20T11:24:33.333 回答
5

我不确定,但我相信其中一种或另一种的速度会根据您使用的编程语言而变化。

我通常更喜欢使用开关。这样代码更容易阅读。

于 2010-04-04T12:47:32.353 回答
3

简短回答:switch 语句更快

if 语句平均需要两次比较(在运行示例代码时)才能找到正确的子句。

无论您有多少不同的情况,switch 语句的平均比较次数都是 1。编译器/VM 将在编译时制作一个可能选项的“查找表”。

如果您经常运行此代码,虚拟机是否可以以类似的方式优化 if 语句?

于 2009-04-20T11:14:58.050 回答
2

由于该语句表达了与您的/链switch相同的意图,但以更受限制、更正式的方式表达,您的第一个猜测应该是编译器将能够更好地优化它,因为它可以得出更多关于代码条件的结论(即只有一个状态可能为真,被比较的值是原始类型等。)当您比较两种相似的语言结构以获得运行时性能时,这是一个非常安全的普遍事实。ifelse

于 2009-04-20T19:25:51.163 回答
2

请参阅 http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.switch%28VS.71%29.aspx

switch statement basically a look up table it have options which are known and if statement is like boolean type. according to me switch and if-else are same but for logic switch can help more better. while if-else helps to understand in reading also.

于 2012-09-29T08:24:12.120 回答