为什么切换比如果更快

106 java switch-statement

我在java中发现很多书说switch语句比if语句更快.但我没有找到说明为什么开关比如果更快的地方.

我有一种情况我必须选择两个中的任何一项我可以使用以下任一方式

switch(item){

case BREAD:
     //eat Bread
break;
default:
    //leave the restaurant

}
Run Code Online (Sandbox Code Playgroud)

或使用if语句如下

if(item== BREAD){
//eat Bread
}else{
//leave the restaurant
}
Run Code Online (Sandbox Code Playgroud)

考虑项目和BREAD是常量int值

在上面的例子中,哪个更快,为什么?

Dan*_*iel 101

因为有很多特殊字节码可以在很多情况下进行高效的switch语句评估.

如果使用IF语句实现,您将进行检查,跳转到下一个子句,检查,跳转到下一个子句等等.通过切换,JVM加载要比较的值并迭代值表以查找匹配,这在大多数情况下更快.

  • @fivetwentysix:不,请参阅以下信息:http://www.artima.com/underthehood/flowP.html.文章引用:当JVM遇到tableswitch指令时,它可以简单地检查键是否在低和高定义的范围内.如果不是,则采用默认分支偏移量.如果是这样,它只是从键中减去低值以获得分支偏移列表中的偏移量.以这种方式,它可以确定适当的分支偏移而不必检查每个案例值. (15认同)
  • 不迭代翻译为"检查,跳转"? (6认同)

Pet*_*rey 31

一个switch说法是并不总是比一个快if言.它比一长串if-else语句更好地扩展,因为它switch可以基于所有值执行查找.但是,对于短暂的情况,它不会更快,可能会更慢.

  • 我怀疑这取决于.对我来说,它的3个或更多表明`switch`会更快更清晰. (9认同)
  • 请限制"长".大于5?大于10?或者更像20 - 30? (2认同)

Hes*_*tig 7

当前的JVM有两种交换字节代码:LookupSwitch和TableSwitch.

switch语句中的每个case都有一个整数偏移量,如果这些偏移量是连续的(或者大部分是连续的,没有大的间隙)(情况0:情况1:情况2等),则使用TableSwitch.

如果偏移以大间隙展开(情况0:情况400:情况93748:等),则使用LookupSwitch.

简而言之,差异在于TableSwitch是在恒定时间内完成的,因为可能值范围内的每个值都被赋予特定的字节码偏移量.因此,当您为语句提供3的偏移量时,它知道向前跳3以找到正确的分支.

查找开关使用二进制搜索来查找正确的代码分支.这在O(log n)时间内运行,这仍然很好,但不是最好的.

有关这方面的更多信息,请参见此处:JVM的LookupSwitch和TableSwitch之间的区别?

因此,就哪一个最快,使用此方法:如果您有3个或更多个值为连续或接近连续的情况,请始终使用开关.

如果您有2个案例,请使用if语句.

对于任何其他情况,切换很可能更快,但不能保证,因为LookupSwitch中的二进制搜索可能会遇到错误的情况.

另外,请记住,JVM将对if语句运行JIT优化,这些语句将尝试将最热门的分支放在代码中.这称为"分支预测".有关这方面的更多信息,请访问:https://dzone.com/articles/branch-prediction-in-java

您的经历可能有所不同 我不知道JVM没有在LookupSwitch上运行类似的优化,但我学会了相信JIT优化,而不是试图超越编译器.

  • 自从发布这篇文章以来,我注意到“开关表达式”和“模式匹配”即将出现在 Java 中,可能最早在 Java 12 中出现。http://openjdk.java.net/jeps/325 http://openjdk .java.net/jeps/305 目前还没有具体的东西,但似乎这些将使 `switch` 成为一个更强大的语言特性。例如,模式匹配将允许更平滑和高效的“instanceof”查找。但是,我认为可以安全地假设对于基本的 switch/if 场景,我提到的规则仍然适用。 (2认同)