Performance 案例vs If Else If:哪个更有效?

Performance 案例vs If Else If:哪个更有效?,performance,switch-statement,if-statement,Performance,Switch Statement,If Statement,可能的重复项: 我又在运行中编码了……当调试器单步执行一个case语句时,它会立即跳转到与条件匹配的项,但是当使用if/else指定相同的逻辑时,它会单步执行每个if语句,直到找到获胜者。case语句是否更有效,或者我的调试器只是在优化步骤?(不要担心语法/错误,我输入了这个,所以,不知道它是否会编译,这是我追求的原则,我不想把它们作为int,因为我模模糊糊地记得一些关于使用带int的偏移量的case的事情)我使用C#,但我对跨编程语言的一般答案感兴趣 switch(myObject.Get

可能的重复项:

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

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

   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{

   }

我认为这只是调试器使它变得简单。 请注意,案例和“如果列表”最终并不相同。案例块通常以“break”结尾是有原因的。案例stmt在汇编中分解时实际上看起来像这样

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”STMT,事实上,如果您在“car”案例中着陆,您将实际运行这两个部分

//do something car     
//do something bike  
GOTO END

我认为,因为cases必须是常量,switch语句与goto语句等效,因此根据变量的值,它跳到正确的case,而在if/then语句中,它必须计算每个表达式

它可以对case语句执行此操作,因为值是编译器常量。这里有更详细的解释

编译器在优化switch语句方面似乎比if语句更好

编译器不知道if语句的求值顺序对您是否重要,因此无法执行任何优化。您可以在if语句中调用方法,从而影响变量。通过switch语句,它知道可以同时计算所有子句,并且可以将它们按最有效的顺序排列

这里有一个小的比较:

调试器正在使它变得更简单,因为您不想单步执行编译器创建的实际代码

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

见密切相关的问题


当然,C#以外的其他语言在实现它时或多或少会有所不同,但开关通常更有效。

许多编程语言优化了开关语句,因此,如果情况是编译器常量,那么它比标准if-else结构快得多。许多语言使用跳转表或索引来优化switch语句。对switch语句进行了很好的讨论。此外,还讨论了C语言中的开关优化

需要注意的一点是switch语句可能被滥用,根据具体情况,最好使用多态性而不是switch语句。请看一个例子。

维基百科相当大,实际上相当不错。有趣的是:

  • 开关本身并不快。它取决于语言、编译器和特定用途
  • 编译器可以使用跳转表或索引函数指针优化开关
  • 该声明的灵感来自(和其他人)的一些有趣的数学

有关使用C开关进行的奇怪而有趣的优化,请参见。

这甚至还没有接近于语言不可知,任何答案都将紧密绑定到一种特定的语言。更不用说特定的编译器和编译器版本了。它可能因语言、编译器和运行时而异。没有办法确定。这甚至不是特定语言的。它完全取决于一个特定的编译器实现,甚至可能不是100%可回答的(例如,可能某些形式的if语句的优化方式不同于其他形式)。顺便说一句:这个问题的真正答案是让它们都实现一个通用的接口/抽象方法,例如
Vehicle#doSomething()
并在具体的实现中定义了每一个,这样你就可以得到
myObject.doSomething()
。我不理解这一部分“你可以在if语句中调用方法,影响变量”在if-else中怎么会发生这种情况?我认为这是一样的,如果(++I){…},你可以这样做,但是在switch-case语句中你不能这样做。