在箭头 (->) 的帮助下切换表达式,现在可以产生/返回值

Jat*_*ish 6 java performance switch-statement jvm-bytecode java-14

Java 14 中扩展的 switch 表达式,除了程序员/审阅者的视觉清晰度之外,switch 表达式的需求并不明确。是吗

  1. 与旧的 switch 表达式不同的字节码实现?
  2. 与以前的版本相比,执行方面有任何性能改进吗?

参考: https: //www.techgeeknext.com/java/java14-features

JDK 14版本:

 int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};
Run Code Online (Sandbox Code Playgroud)

JDK 14 字节代码

   0: iconst_1
   1: istore_1
   2: iload_1
   3: tableswitch   { // 1 to 7
                 1: 44
                 2: 44
                 3: 44
                 4: 49
                 5: 54
                 6: 54
                 7: 59
           default: 64
      }
  44: bipush        6
  46: goto          65
  49: bipush        7
  51: goto          65
  54: bipush        8
  56: goto          65
  59: bipush        9
  61: goto          65
  64: iconst_0
  65: istore_2
  66: return
Run Code Online (Sandbox Code Playgroud)

JDK-10 代码

int numLetters;
int day = 1;
switch (day) {
  case 1:
  case 2:
  case 3:
    numLetters = 6;
    break;
  case 4:
    numLetters = 7;
    break;
  case 5:
  case 6:
    numLetters = 8;
    break;
  case 7:
    numLetters = 9;
    break;
  default:
    numLetters = 0;
}
Run Code Online (Sandbox Code Playgroud)

JDK - 10 字节代码

   0: iconst_1
   1: istore_2
   2: iload_2
   3: tableswitch   { // 1 to 7
                 1: 44
                 2: 44
                 3: 44
                 4: 50
                 5: 56
                 6: 56
                 7: 62
           default: 68
      }
  44: bipush        6
  46: istore_1
  47: goto          70
  50: bipush        7
  52: istore_1
  53: goto          70
  56: bipush        8
  58: istore_1
  59: goto          70
  62: bipush        9
  64: istore_1
  65: goto          70
  68: iconst_0
  69: istore_1
  70: return
Run Code Online (Sandbox Code Playgroud)

除了块内的本地分配减少了 JIT 指令之外,原语没有重大区别。

Hol*_*ger 6

switchover一样String,字节码没有\xe2\x80\x99 改变,而且没有必要改变。

\n\n

虽然字节码是专门为编译 Java 源代码的目标而设计的,但它\xe2\x80\x99s 并没有以同样的方式受到限制。另请参见Java 语言中不可用的字节码功能\xe2\x80\xa6

\n\n

switch表达式利用了以前普通 Java 代码不使用的功能,但肯定被自动代码生成器或针对 JVM 的其他编程语言的编译器使用,可以在 switch 情况的不同分支中将值推送到操作数堆栈,在合并点之后使用。对于好的旧switch语句,您始终必须将值存储到局部变量中并在合并点之后加载它。

\n\n

\xe2\x8c\xa9 普通 Java 代码未利用但可与 Java 字节码顺利配合的另一个功能是(ab)使用 switch 指令来生成奇特的循环,只需在 switch 指令之前设置目标位置即可。谁知道某些源代码功能是否会在未来的语言版本中利用它\xe2\x80\xa6\xe2\x8c\xaa

\n\n

但是否使用中间局部变量应该没有多大关系。在优化器将代码转换为SSA 形式之后,甚至在其他代码转换和优化应用之前,局部变量和操作数堆栈之间的所有传输都将被消除。

\n\n

这并不能排除由于特定实现(版本)中 switch 指令的细微变化而导致的令人惊讶的性能差异。

\n