元组的多重赋值比多个赋值语句慢吗?

时间:2014-09-21 14:41:42

标签: scala syntax microbenchmark

使用元组分配多个变量并在多个语句中分配它们之间是否存在差异?

例如,以下代码段之间是否存在差异?

// multiple assignment using tuples
val (x, y) = (str.length, str.substring(1, 2))

// multiple-statement assignment
val x = str.length
val y = str.substring(1, 2)

1 个答案:

答案 0 :(得分:3)

的区别。使用元组的方法实际上是调用一个提取器(unapply方法),这会在运行时产生成本。第二种方法肯定更快。

为了了解这种差异,下面是两种方法的反编译,显示了这两种方法。您可以清楚地看到第一种方法如何导致更多操作。

这里需要注意的一点是,第一个表达式需要自动装箱到java.lang.Integer(因为Tuple2接受对象),而第二个表达式使用没有装箱的值。

  public void m1(java.lang.String);
    Code:
       0: new           #16                 // class scala/Tuple2
       3: dup           
       4: aload_1       
       5: invokevirtual #22                 // Method java/lang/String.length:()I
       8: invokestatic  #28                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
      11: aload_1       
      12: iconst_1      
      13: iconst_2      
      14: invokevirtual #32                 // Method java/lang/String.substring:(II)Ljava/lang/String;
      17: invokespecial #35                 // Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      20: astore_3      
      21: aload_3       
      22: ifnull        75
      25: aload_3       
      26: invokevirtual #38                 // Method scala/Tuple2._1$mcI$sp:()I
      29: istore        4
      31: aload_3       
      32: invokevirtual #42                 // Method scala/Tuple2._2:()Ljava/lang/Object;
      35: checkcast     #18                 // class java/lang/String
      38: astore        5
      40: new           #16                 // class scala/Tuple2
      43: dup           
      44: iload         4
      46: invokestatic  #28                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
      49: aload         5
      51: invokespecial #35                 // Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
      54: astore        6
      56: aload         6
      58: astore_2      
      59: aload_2       
      60: invokevirtual #38                 // Method scala/Tuple2._1$mcI$sp:()I
      63: istore        7
      65: aload_2       
      66: invokevirtual #42                 // Method scala/Tuple2._2:()Ljava/lang/Object;
      69: checkcast     #18                 // class java/lang/String
      72: astore        8
      74: return        
      75: new           #44                 // class scala/MatchError
      78: dup           
      79: aload_3       
      80: invokespecial #47                 // Method scala/MatchError."<init>":(Ljava/lang/Object;)V
      83: athrow        

  public void m2(java.lang.String);
    Code:
       0: aload_1       
       1: invokevirtual #22                 // Method java/lang/String.length:()I
       4: istore_2      
       5: aload_1       
       6: iconst_1      
       7: iconst_2      
       8: invokevirtual #32                 // Method java/lang/String.substring:(II)Ljava/lang/String;
      11: astore_3      
      12: return        
}