当前位置:  开发笔记 > 编程语言 > 正文

在C#中使用if/else和switch-case之间是否有任何显着差异?

如何解决《在C#中使用if/else和switch-case之间是否有任何显着差异?》经验,为你挑选了7个好方法。

在C#中使用switch语句与使用语句的好处/缺点是什么?if/else我无法想象除了你的代码外观之外还有其他重大差异.

是否有任何理由导致生成的IL或相关的运行时性能完全不同?

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

ima.. 325

SWITCH语句仅在调试或兼容模式下生成与IF相同的程序集.在发布中,它将被编译成跳转表(通过MSIL'witch'语句) - 即O(1).

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

但是如果条件的数量足以覆盖开销,C#编译器将创建一个HashTable对象,用字符串常量填充它并在该表上进行查找,然后跳转.Hashtable查找不是严格的O(1)并且具有明显的恒定成本,但是如果案例标签的数量很大,则它将比与IF中的每个字符串常量相比明显更快.

总而言之,如果条件数大于5,则优先选择SWITCH,否则使用看起来更好的东西.



1> ima..:

SWITCH语句仅在调试或兼容模式下生成与IF相同的程序集.在发布中,它将被编译成跳转表(通过MSIL'witch'语句) - 即O(1).

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

但是如果条件的数量足以覆盖开销,C#编译器将创建一个HashTable对象,用字符串常量填充它并在该表上进行查找,然后跳转.Hashtable查找不是严格的O(1)并且具有明显的恒定成本,但是如果案例标签的数量很大,则它将比与IF中的每个字符串常量相比明显更快.

总而言之,如果条件数大于5,则优先选择SWITCH,否则使用看起来更好的东西.


一些实验表明,计数<= 6:"if"; count> = 7:字典.那就是MS .NET 3.5 C#编译器 - 它当然可以在版本和供应商之间进行更改.
嘿,我欠你一个道歉.抱歉是个骨头.
我想大约十个.20为安全起见.顺便说一下,我的愤怒不是你,而是人们的支持和接受.
我只是好奇

2> Scott Wisnie..:

通常(考虑所有语言和所有编译器),switch语句CAN SOMETIMES比if/else语句更有效,因为编译器很容易从switch语句生成跳转表.在给定适当约束的情况下,可以对if/else语句执行相同的操作,但这要困难得多.

在C#的情况下,这也是正确的,但出于其他原因.

使用大量字符串时,使用switch语句具有显着的性能优势,因为编译器将使用哈希表来实现跳转.

使用少量字符串,两者之间的性能是相同的.

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

有一个"switch语句"MSIL指令,当jitted将使用跳转表来实现switch语句.它只适用于整数类型(但这个问题询问字符串).

对于少量字符串,编译器生成IF/ELSE块更有效,然后使用哈希表.

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

这是错的.'IMA'非常友好地指出了这一点(嗯......他对此不好,但他是对的,我错了,这是重要的部分)

我还对MSIL中缺少"切换"指令做了一个假设(我想,如果有一个切换原语,为什么他们不使用哈希表,所以一定不能有切换原语. ......)这既错了,又让我非常愚蠢.再次'IMA'向我指出了这一点.

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

但是,我已经把它作为社区Wiki,因为我觉得我不配错了REP.如果你有机会,请投票'ima'的帖子.


ima,如果有错误,请指出它们.斯科特很乐意纠正这个帖子.如果没有,那些已经达到纠正答案能力的人就会这样做.这是这样一个网站运作的唯一方式,而且看起来一般情况下它都有效.或者拿球回家:)
我所能做的只是为犯一个愚蠢的错误而道歉.相信我,我对此感到愚蠢.说真的,我认为这仍然是最好的答案.在本机编译器中,可以使用哈希表来实现跳转,因此这不是一些可怕的错误.我犯了一个错误.
@ima如果您认为答案是客观错误的,那么将其编辑为正确.这就是每个人都可以编辑答案的原因.
MSIL中有一个switch原语,c#语句通常会编译成类似C的查找.在某些情况下(目标平台,cl交换机等),交换机可能会在编译期间扩展为IF,但它只是一个后备兼容性度量.
@Scott:我建议您编辑第二和第三段以明确说明"for strings".人们可能不会在底部阅读更新.

3> Norman Ramse..:

有三个理由更喜欢switch:

针对本机代码的编译器通常可以将switch语句编译为一个条件分支加上间接跳转,ifs 序列需要一系列条件分支.根据案件的密度,已经写了很多关于如何有效地编写案例陈述的学术论文; 一些是从lcc编译器页面链接的.(Lcc拥有一个更具创新性的交换机编译器.)

switch语句是互斥备选方案中的一种选择,并且switch语法使得该控制流程对程序员更加透明,然后是if-then-else语句的嵌套.

在某些语言中,包括绝对ML和Haskell,编译器会检查您是否遗漏了任何案例.我认为这个功能是ML和Haskell的主要优点之一.我不知道C#是否可以做到这一点.

一则轶事:在他获得终身成就奖的一次演讲中,我听到Tony Hoare说他在职业生涯中所做的一切,他最为自豪的有三件事:

发明Quicksort

发明switch语句(Tony称之为case语句)

开始和结束他在工业界的职业生涯

无法想象没有生活switch.



4> 小智..:

编译器将几乎所有的东西都优化到相同的代码中,只有很小的差异(Knuth,任何人?).

区别在于switch语句比十五个if else语句串起来更清晰.

朋友不要让朋友堆叠if-else语句.


"朋友不要让朋友堆叠if-else语句." 你应该做一个bumber sitcker :)

5> kemiller2002..:

实际上,switch语句更有效.编译器会将它优化为一个查找表,其中if/else语句不能.缺点是switch语句不能与变量值一起使用.
你做不到:

switch(variable)
{
   case someVariable
   break;
   default:
   break;
}

它一定要是

switch(variable)
{
  case CONSTANT_VALUE;
  break;
  default:
  break;
}



6> Mark Bessey..:

我没有看到其他人提出(显而易见的?)这一点,即switch语句的假设效率优势取决于各种情况大致相同.在一个(或几个)值更可能的情况下,if-then-else梯形图可以更快,通过确保首先检查最常见的情况:

所以,例如:

if (x==0) then {
  // do one thing
} else if (x==1) {
  // do the other thing
} else if (x==2) {
  // do the third thing
}

VS

switch(x) {
  case 0: 
         // do one thing
         break;
  case 1: 
         // do the other thing
         break;
  case 2: 
         // do the third thing
         break;
}

如果x在90%的时间内为零,则"if-else"代码的速度可以是基于交换机的代码的两倍.即使编译器将"开关"转换为某种聪明的表驱动goto,它仍然不会像检查零那样快.


最初的问题(三年前!)刚问及if/else和switch之间的优缺点.这是一个例子.我亲眼看到这种优化在例程的运行时间上产生了显着的差异.
没有过早的优化!一般来说,如果你有不止一些情况并且它们与`switch`兼容,那么`switch`语句更好(更可读,有时更快).*如果你知道*一个案例更有可能,你可以把它拉出来形成一个`if`-`else`-`witch`结构和*如果它快得多*,你就把它留下来.(重复,如果需要.)IMO仍然相当可读.如果`switch`退化并变得太小,正则表达式替换将完成将其转换为`else if`链的大部分工作.

7> gbjbaanb..:

通常它会看起来更好 - 也就是说更容易理解发生了什么.考虑到性能优势最多只是极其微小,代码视图是最重要的区别.

因此,如果if/else看起来更好,请使用它,否则使用switch语句.

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有