使用if / else和switch之间是否存在显着差异?

在C#中使用switch语句与if/else相比,有什么好处/不利之处。 我无法想象有什么大不同,除了你的代码的外观。

为什么产生的IL或相关的运行时性能会有根本的不同?

相关:什么是更快,打开字符串或elseif的类型?


在调试或兼容模式下,SWITCH语句只产生与IF相同的程序集。 在发行版中,它将被编译到跳转表中(通过MSIL'switch'语句) - 这是O(1)。

C#(与许多其他语言不同)也允许打开字符串常量 - 这有点不同。 为任意长度的字符串建立跳转表显然是不实际的,所以大多数情况下,这种开关将被编译成IF堆栈。

但是,如果条件数量足够大以涵盖开销,C#编译器将创建一个HashTable对象,使用字符串常量填充它,并在该表上进行查找,然后跳转。 散列表查找并不严格地为O(1),并且具有明显的不变成本,但如果个案标签的数量很大,则它将比IF中的每个字符串常量比较快得多。

总结一下,如果条件数量超过5个,更喜欢用IF来切换,否则用更好看的。


通常(考虑所有语言和所有编译器),switch语句CAN SOMETIMES比if / else语句更有效,因为编译器很容易从switch语句生成跳转表。 给定适当的约束条件,可以对if / else语句做同样的事情,但这会更困难。

在C#的情况下,这也是事实,但是由于其他原因。

使用大量字符串时,使用switch语句会带来显着的性能优势,因为编译器将使用散列表来实现跳转。

对于少量的字符串,两者之间的性能是相同的。

这是因为在那种情况下,C#编译器不会生成跳转表。 相反,它会生成等效于IF / ELSE块的MSIL。

有一个“switch语句”MSIL指令,当jitter使用跳转表来实现一个switch语句时。 它只适用于整数类型,但是(这个问题询问关于字符串)。

对于少量字符串,编译器生成IF / ELSE块的效率更高,然后使用散列表。

当我最初注意到这一点时,我做了一个假设,因为IF / ELSE块只与少量字符串一起使用,所以编译器对大量字符串进行了相同的转换。

这是错误的。 'IMA'非常友善地向我指出了这一点(呃...他对此并不友善,但他是对的,我错了,这是重要的部分)

我还做了一个关于MSIL中缺少“开关”指令的假设(我想,如果有一个开关原语,为什么他们不使用它与一个哈希表,所以一定不能有一个开关原语。 ...)。 这对我来说都是错误的,也是非常愚蠢的。 'IMA'再一次向我指出了这一点。

我在这里做了更新,因为它是评分最高的帖子,也是接受的答案。

不过,我已经将它制作成社区维基,因为我认为我不值得因为错误而接受REP。 如果你有机会,请投票给“ima”的帖子。


选择switch三个理由:

  • 针对本地代码的编译器通常可以将switch语句编译为一个条件分支加间接跳转,if序列if需要一系列条件分支 。 根据病例的密度,已经撰写了大量关于如何有效编译病例报告的学术论文; 有些链接来自lcc编译器页面。 (Lcc拥有更具创新性的开关编译器之一。)

  • switch语句是互斥选项之间的一种选择,并且switch语法使得该控制流程对程序员来说更加透明,然后嵌套if-then-else语句。

  • 在某些语言中,绝对包括ML和Haskell, 编译器会检查是否遗漏了任何情况 。 我认为这是ML和Haskell的主要优势之一。 我不知道C#是否可以做到这一点。

  • 一个奇闻轶事:在听取了终身成就奖的演讲中,我听到托尼霍尔说,在他的职业生涯中所做的所有事情中,有三个是他最引以为豪的:

  • 发明Quicksort
  • 发明switch语句(托尼称为case陈述)
  • 开始和结束他的行业生涯
  • 无法想象没有switch生活

    链接地址: http://www.djcxy.com/p/84483.html

    上一篇: Is there any significant difference between using if/else and switch

    下一篇: Switch Fall Through Not Working as Expected