在C#中使用if/else和switch-case之间有什么重大区别吗?
在C#中使用if/else和switch-case之间有什么重大区别吗?
在C#中,使用switch
语句与使用if/else
语句相比,有何好处/不利之处?除了代码的外观可能有所不同之外,我无法想象它们有太大的区别。
是否有任何原因导致生成的IL代码或相关的运行时性能会有很大的差异?
相关链接:字符串上的switch和类型上的elseif哪个更快?
在C#中,使用if/else和switch-case是否有明显的差异?
在C#中,使用if/else和switch-case语句来处理条件判断时,在调试模式或兼容模式下,它们生成的程序集是相同的。但在发布模式下,switch-case语句会被编译成跳转表(通过MSIL 'switch'语句),其时间复杂度为O(1)。
与许多其他语言不同,C#还允许在字符串常量上使用switch-case语句,但处理方式略有不同。对于任意长度的字符串构建跳转表显然是不实际的,因此大多数情况下,这种switch-case语句会被编译成一系列的if/else语句。
但如果条件的数量足够多以覆盖开销,C#编译器将创建一个HashTable对象,将字符串常量填充到其中,并在该表上进行查找,然后跳转。HashTable的查找时间复杂度不是严格的O(1),并且有明显的常数开销,但如果case标签的数量很大,它将比在if/else语句中逐个比较字符串常量要快得多。
总结一下,如果条件的数量超过5个左右,建议使用switch-case语句,否则使用哪种语句看起来更好就可以了。
你确定C#编译器会生成一个HashTable吗?我在上面的评论讨论中提到的哈希表是关于本地编译器的,而不是C#编译器。C#编译器使用什么阈值来生成哈希表?
我认为是大约10个。为了保险起见,使用20个。顺便说一下,我的愤怒不是针对你,而是针对那些点赞和接受的人。
一些实验表明,当条件数量小于等于6时,使用"if"语句更快;当条件数量大于等于7时,使用字典(HashTable)更快。这是使用MS .NET 3.5的C#编译器得出的结果,不同版本和供应商可能会有所不同。
作为后续,对于实际应用程序来说,大多数情况下是否有任何实际差异?我发现在C#中使用switch语句有些奇怪,它们的语法与其他语句不太相似,我发现它们会使我的代码更难读,是否值得使用switch语句,或者只有在遇到性能瓶颈时才回来替换它们?
我对我们应用程序中使用的18个字符串(长度为3-35个字符)进行了具体的测试。使用if/else语句比较快,快了18%。
肯定会有一些特殊情况不符合平均规则。例如,如果你90%的测试都匹配第一个if语句,那么使用if/else if语句对于你的情况来说会更快,而不是平均情况下所有结果都是等概率的假设。
当然,如果我对进入字符串的分布有先验信息,那么我可以编写更高效的代码。
在C#中使用if/else和switch-case是否有显著的区别?这个问题的出现的原因是,编译器会将几乎所有内容优化为相同的代码,只有细微的差异。解决方法是使用switch语句比使用串联的十五个if/else语句更清晰。朋友们不要让朋友们堆叠if/else语句。
在C#中,if/else语句和switch-case语句是两种常用的条件控制结构。它们可以根据条件的不同来执行不同的代码块。尽管它们都可以实现相同的功能,但在某些情况下,使用switch-case语句可能更清晰和更有效。
首先,让我们来看看编译器如何处理这两种语句。根据Knuth的观点,编译器会将几乎所有内容优化为相同的代码,只有细微的差异。这意味着在大多数情况下,使用if/else语句和switch-case语句不会对代码的执行效率产生显著影响。
然而,尽管编译器会优化代码,但使用switch-case语句可能会使代码更清晰易读。当我们有多个条件需要判断时,使用多个if/else语句可能会使代码变得冗长和难以理解。相比之下,使用switch-case语句可以将多个条件组织在一起,使代码更加简洁和可读性更高。
此外,使用switch-case语句还可以提供更好的扩展性。当我们需要添加更多条件时,只需要在switch语句中添加更多的case分支。而使用if/else语句时,我们需要在代码中添加更多的if else语句,这可能会导致代码的可维护性变差。
因此,虽然在大多数情况下,if/else语句和switch-case语句之间的差异并不显著,但在代码的可读性和可维护性方面,使用switch-case语句可能更具优势。所以,朋友们不要让朋友们堆叠if/else语句,而是尽可能使用switch-case语句来提高代码的可读性和可维护性。
在C#中,使用if/else语句和switch-case语句之间是否有显著差异呢?这个问题的出现原因是,对于所有的语言和编译器来说,switch语句有时比if/else语句更高效,因为编译器很容易从switch语句生成跳转表。而对于if/else语句来说,如果给定适当的约束条件,也可以实现相同的效果,但这要困难得多。
在C#中,这也是正确的,但原因不同。对于大量的字符串,使用switch语句有显著的性能优势,因为编译器会使用哈希表来实现跳转。对于小量的字符串,两者的性能是相同的。这是因为在这种情况下,C#编译器不会生成跳转表,而是生成等效于if/else块的MSIL。
在MSIL中有一个“switch语句”指令,当被JIT编译时,将使用跳转表来实现switch语句。然而,它只适用于整数类型,而不适用于字符串类型。
对于小量的字符串来说,编译器生成if/else块比使用哈希表更高效。当我最初注意到这一点时,我做出了错误的假设,认为由于使用了少量的字符串,编译器对于大量的字符串也会进行同样的转换。这是错误的,IMA指出了这一点。
此外,我还对MSIL中缺少“switch”指令做出了错误的假设(我认为,如果有一个switch原语,为什么不使用它与哈希表一起使用,所以可能没有switch原语...)。这个错误同样愚蠢。IMA再次指出了这一点。
我在这里进行了更新,因为它是评分最高的帖子,也是被接受的答案。然而,我将其设为社区Wiki,因为我认为我不应该因为错误而得到声望。如果有机会,请给IMA的帖子点赞。
在MSIL中有一个switch原语,并且C#语句通常编译成类似于C的查找。在某些情况下(目标平台、cl开关等),switch可能在编译过程中被扩展为if语句,但这只是一种兼容性措施。
好吧...是的,确实有一个switch指令。对不起。switch指令不适用于字符串类型。我更新了我的回答。谢谢你的纠正。
很抱歉你有这样的感觉。我说的大部分都是正确的,只是有一个小错误,你帮助我修正了它。我认为Stack Overflow在这方面做得很好。
我只能为自己的愚蠢错误道歉。相信我,我对此感到非常愚蠢。但是,我认为这仍然是最好的答案。在本机编译器中,使用哈希表来实现跳转是可能的,所以这并不是什么严重的错误。我只犯了一个错误。
IMA,如果有错误,请指出。Scott会乐意纠正帖子。如果没有,其他有能力更正答案的人也会这样做。这是这个网站运行的唯一方式,而且似乎总体上是有效的。或者你可以带着你的球回家:)。
编译器可能会将大型switch语句优化为二分搜索,而对于if/else块,则可能不会这样做。
我建议你编辑第二和第三段,明确指出“对于字符串”。人们可能不会读到底部的更新。
(顺便说一句,我在这个问题中没有看到任何关于它是关于字符串的说法。它被标记为字符串问题的重复,但这个问题本身并没有说。)
正如上面第5段所提到的,从哪个条件开始,C#编译器将生成“跳转表”。因为你说对于小条件它不会生成。