Java-JDK 14-借助箭头(->)切换表达式,现在可以产生/返回值

问题描述 投票:0回答:1

Java 14中扩展的开关表达式,除了程序员/查看者的视觉清晰度外,开关表达式的需求尚不清楚。是-

  1. 与较早的开关表达式不同的字节码实现?
  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;
};

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

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;
}

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

除了在块内的局部分配减少了JIT指令之外,对于基元没有太大区别。

java performance switch-statement jvm-bytecode
1个回答
0
投票

[像switch超过String一样,字节码没有变化,因此没有必要。

虽然字节码是专门为编译Java源代码而设计的,但并没有相同的限制。另请参见Bytecode features not available in the Java language

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

〈另一个普通Java代码未利用的功能,但与Java字节码可以正常使用的另一个功能是,通过仅在switch指令之前放置目标位置,来(使用)switch指令产生奇特的循环。谁知道将来的语言版本中是否会使用某些源代码功能……〉

但是无论是否使用中间局部变量,都没有太大关系。在优化程序将代码转换为SSA form之后,甚至在应用其他代码转换和优化之前,就消除了局部变量和操作数堆栈之间的所有传输。

这不排除在特定实现(版本)中对切换指令进行细微更改而导致的surprising performance differences

© www.soinside.com 2019 - 2024. All rights reserved.