Hosam Aly
Hosam Aly

Reputation: 42463

Is multiple assignment of tuples slower than multiple assignment statements?

Is there a difference between assigning multiple variables using a tuple, and assigning them in multiple statements?

For example, is there a difference between the following code snippets?

// 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)

Upvotes: 3

Views: 159

Answers (1)

Hosam Aly
Hosam Aly

Reputation: 42463

There is a difference. The approach of using tuples is actually invoking an extractor (the unapply method), which would incur a cost at runtime. The second approach is certainly faster.

To get an idea about the difference, here is a decompilation of two methods showing both approaches. You can see clearly how the first approach causes much more operations.

An important point to note here is that the first expression requires auto-boxing to a java.lang.Integer (because Tuple2 accepts objects), while the second expression uses the value without boxing.

  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        
}

Upvotes: 3

Related Questions