Представление и эффективность операторов Switch в байт-коде? - PullRequest
3 голосов
/ 05 января 2012

Хотя оператор переключения может быть представлен в виде серии операторов if, похоже, что когда оператор переключения Java компилируется в байт-код, используется другой подход.

  • Какое представление использует байт-код?
  • Я предполагаю, что это альтернативное представление по соображениям эффективности, так как же эффективность сравнивается с эффективностью представления оператора if?
  • Есть ли другие соображения, которые привели к использованию этого представления?

Ответы [ 2 ]

4 голосов
/ 06 января 2012

Прочитайте spec . В Java, если вы кодируете оператор switch, то в зависимости от различных вещей переключатель преобразуется в инструкцию tablewitch в байт-коде. По сути, прыжковый стол. Однако то, как выглядит байт-код, может быть неуместным, если JIT может оптимизировать его в нечто более эффективное. Это, конечно, зависит от платформы.

0 голосов
/ 06 января 2012

Рассмотрим этот простой пример 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 (из приведенного выше кода) будет массивом / справочной таблицейметок (читай: смещения) к местам в функции, где появились блоки кода случая.

РЕДАКТИРОВАТЬ

В Java вышеприведенный случай переключения будет скомпилирован вследующий байт-код

[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
...