字节码中Switch语句的表示和效率?

时间:2012-01-05 19:54:24

标签: java performance switch-statement bytecode representation

虽然switch语句可以表示为一系列if语句,但是当Java switch语句被编译成字节码时,似乎使用了不同的方法。

  • 字节码使用的表示形式是什么?
  • 我认为这种替代表示是出于效率的原因,那么效率如何与if语句表示相比呢?
  • 是否还有其他考虑因素导致使用此表示形式?

2 个答案:

答案 0 :(得分:4)

阅读spec。在Java中,如果编写switch语句,那么根据各种事情,交换机将转换为字节码中的tableswitch指令。本质上是一个跳转表。如果JIT可以将其优化为更高效的东西,那么字节码看起来可能是无关紧要的。这当然取决于平台。

答案 1 :(得分:0)

考虑这个简单的JavaScript示例

var SwitchCases = [
// case 1
 function() { return "one"; },
// case 2
 function() { return "two"; },
// case 3
 function() { return "three"; },
// default
 function() { return ""; }
];
var SwitchCaseMin = 1;
var SwitchCaseMax = 3;
var SwitchCaseDefault = true;

function FakeSwitchCase(switch) {
 if(switch > SwitchCaseMax || switch < SwitchCaseMin) {
  if(SwitchCaseDefault == true) {
   return SwitchCases[SwitchCases.length-1]();
  }
 } else {
  return SwitchCases[switch - SwitchCaseMin]();
 }
}

关键部分是

SwitchCases[switch - SwitchCaseMin]();

想象一下,如果有很多情况下评估它们的代码不会增大,但是如果我们使用IF ..ELSE IF ... ELSE,执行时间会随着每个添加的情况而增长。

在真正的交换机案例实现中,SwitchCases(来自上面的代码)将是一个标签的数组/查找表(读取:偏移)到函数中出现Case代码块的位置。

修改

在java中,上面的switch案例将编译为以下字节代码

[tableswitch 0xAA]
[padding bytes 0x00 or 0x0000 or 0x000000]
[offset of SwitchCases[3]] // default case
[SwitchCaseMin] // 1
[SwitchCaseMax] // 3
[offset of SwitchCases[0]] // case 1
[offset of SwitchCases[1]] // case 2
[offset of SwitchCases[2]] // case 3