关于性能:case与if else if:哪个更有效?

Case vs If Else If: Which is more efficient?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicates:
is “else if” faster than “switch() case” ?
What is the relative performance of if/else vs. switch in Java?

我又在运行中编码了……当调试器单步执行case语句时,它会立即跳转到与条件匹配的项,但是当使用if/else指定相同的逻辑时,它会单步执行every if语句,直到找到获胜者。case语句更有效,还是我的调试器只是在优化步骤?(不要担心语法/错误,我把它输入了so,不知道它是否会编译,这是我所追求的原则,我不想把它们作为in t,因为我模糊地记得一些关于case使用带in t的偏移量的情况)我使用c,但我对跨编程语言的一般答案感兴趣。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
switch(myObject.GetType()){

    case typeof(Car):
        //do something
        break;

    case typeof(Bike):
        //do something
        break;

    case typeof(Unicycle):
        //do something
        break;

    case default:
        break;
}

VS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   Type myType = myObject.GetType();

   if (myType == typeof(Car)){
            //do something
   }

   else if (myType == typeof(Bike)){
            //do something
   }

   else if (myType == typeof(Unicycle)){
            //do something
   }
   else{

   }


似乎编译器在优化switch语句方面优于if语句。

编译器不知道计算if语句的顺序对您是否重要,并且无法在那里执行任何优化。您可以在if语句中调用方法,从而影响变量。使用switch语句,它知道所有子句都可以同时进行计算,并且可以将它们按最有效的顺序放置。

下面是一个小的比较:http://www.blackwasp.co.uk/speedtestifelswitch.aspx


调试器使其更简单,因为您不想单步执行编译器创建的实际代码。

如果开关包含五个以上的项,则使用查找表或哈希表实现,否则使用if..else实现。

看到密切相关的问题是"else if"快于"switch()case"?.

当然,除了C语言以外的其他语言或多或少也会实现它,但是切换通常更有效。


许多编程语言都对switch语句进行了优化,因此如果结构提供的情况是编译器常量,那么它比标准if else快得多。许多语言使用跳转表或索引分支表来优化switch语句。维基百科对switch语句有很好的讨论。此外,本文还讨论了C语言中的开关优化问题。

需要注意的一点是,switch语句可能会被滥用,根据具体情况,最好使用多态性而不是switch语句。请参阅此处以获取示例。


维基百科的switch语句条目相当大,实际上相当好。有趣的地方:

  • 开关本身并不快。它取决于语言、编译器和特定用途。
  • 编译器可以使用跳转表或索引函数指针优化开关。
  • 这个声明是由斯蒂芬克莱恩(以及其他人)的一些有趣的数学启发而来的。

有关使用C开关进行的奇怪而有趣的优化,请参阅Duff的设备。


它可以对case语句执行此操作,因为值是编译器常量。这里有一个更详细的解释:http://sequence-points.blogspot.com/2007/10/why-is-switch-statement-faster-than-if.html


我相信,因为cases必须是常量值,switch语句实现goto的相等性,因此基于变量的值,它跳到正确的case,而在if/then语句中,它必须计算每个表达式。


我认为这只是使它简单化的调试器。请注意,案例和"if list"最终是不同的。有一个原因可以解释为什么事例块通常以"break"结尾。案例stmt在组装中分解时实际上看起来像这样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if myObject.GetType() == type of Car
    GOTO START_CAR
else if myObject.GetType() == type of Bike
    GOTO START_BIKE

LABEL START_CAR
//do something car    
GOTO END

LABEL START_BIKE
//do something bike  
GOTO END

LABEL END

如果你没有休息,那么箱子块会丢失"goto end"stmts,事实上,如果你落在"car"箱子里,你实际上会运行这两个部分。

1
2
3
//do something car    
//do something bike  
GOTO END