在C#中使用if/etc和Switch-case有什么显著的区别吗?

在C#中使用if/etc和Switch-case有什么显著的区别吗?

使用switch语句诉aif/else在C#。我无法想象有那么大的不同,除了您的代码的外观。

产生的IL或相关的运行时性能会有根本不同的原因吗?

有关:什么更快,打开字符串还是输入?


慕的地8271018
浏览 677回答 3
3回答

慕码人2483693

开关语句仅在调试或兼容模式下生成与IFS相同的程序集。在发行版中,它将被编译成跳转表(通过MSIL‘Switch’语句)-即O(1)。C#(与许多其他语言不同)也允许打开字符串常量-这有点不同。显然,为任意长度的字符串构建跳转表是不实际的,因此这类开关通常会被编译到IFS堆栈中。但是,如果条件的数量足够大,足以覆盖开销,C#编译器将创建一个HashTable对象,用字符串常量填充它,然后对该表进行查找,然后进行跳转。Hashtable查找不是严格意义上的O(1),并且具有明显的恒定成本,但是如果大小写标签的数量很大,它将比IFS中的每个字符串常量要快得多。总之,如果条件数超过5,则更倾向于切换if,否则使用任何看起来更好的。

四季花海

通常(考虑所有语言和所有编译器),开关语句有时比if/etc语句更有效,因为编译器很容易从Switch语句生成跳转表。在适当的约束条件下,可以对if/etc语句执行同样的操作,但这要困难得多。对于C#,这也是正确的,但出于其他原因。对于大量的字符串,使用Switch语句具有显著的性能优势,因为编译器将使用哈希表来实现跳转。对于少量的字符串,两者之间的性能是相同的。这是因为在这种情况下,C#编译器不生成跳转表。相反,它会生成相当于if/etc块的msil。有一个“Switch语句”msil指令,当被抛出时,它将使用一个跳转表来实现一个Switch语句。但是,它只适用于整数类型(这个问题询问字符串)。对于少量的字符串,编译器生成if/etc块的效率更高,然后使用哈希表。当我最初注意到这一点时,我假设因为if/etc块与少量字符串一起使用,所以编译器对大量字符串进行了相同的转换。这是不对的。“IMA”很好地向我指出了这一点(嗯.他对此并不友善,但他是对的,而我错了,这是最重要的部分)我还对msil中缺少“开关”指令做了一个愚蠢的假设(我想,如果有一个开关原语,他们为什么不将它与哈希表一起使用,所以必须没有开关原语.)。这两件事都是错的,对我来说也是非常愚蠢的。“IMA”再次向我指出了这一点。我在这里做了更新,因为它是评分最高的帖子,也是公认的答案。然而,我把它变成了CommunityWiki,因为我觉得我不应该因为错误而得到代表。如果你有机会,请投“IMA”一票。

qq_花开花谢_0

选择switch:针对本机代码的编译器通常可以将开关语句编译为一个有条件的分支加上一个间接跳转鉴于ifS需要一个条件分支序列..根据案例的密度,已经编写了大量关于如何高效编译案例陈述的学术论文;有些是从LCC编译器页..(LCC有一个更创新的开关编译器。)开关语句是在相互排斥的备选方案中进行选择和开关语法使此控制流对程序员更透明。然后是一窝如果-然后-否则的语句。在某些语言中,包括绝对ML和Haskell,编译器检查是否遗漏了任何情况。..我认为这个特性是ML和Haskell的主要优势之一。我不知道C#能不能这么做。一件轶事:在他获得终身成就奖的演讲中,我听到托尼·霍尔说,在他职业生涯中所做的所有事情中,有三件是他最自豪的:发明快速排序发明开关语句(托尼称之为case声明)开始和结束他的工业生涯I 无法想象没有switch.
打开App,查看更多内容
随时随地看视频慕课网APP