使用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#是否可以做到这一点。
一个奇闻轶事:在听取了终身成就奖的演讲中,我听到托尼霍尔说,在他的职业生涯中所做的所有事情中,有三个是他最引以为豪的:
case
陈述) 我无法想象没有switch
生活 。
上一篇: Is there any significant difference between using if/else and switch