加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么Scala在解包元组时会构造一个新的元组?

发布时间:2020-12-16 08:54:48 所属栏目:安全 来源:网络整理
导读:为什么这个 Scala代码: class Test{ def foo: (Int,String) = { (123,"123") } def bar: Unit = { val (i,s) = foo }} 为bar()生成以下字节码,构造一个新的Tuple2,将Tuple2从foo()传递给它,然后从中获取值? public void bar();Code: 0: aload_0 1: invokev
为什么这个 Scala代码:

class Test
{
  def foo: (Int,String) =
  {
    (123,"123")
  }

  def bar: Unit =
  {
    val (i,s) = foo
  }
}

为bar()生成以下字节码,构造一个新的Tuple2,将Tuple2从foo()传递给它,然后从中获取值?

public void bar();
Code:
 0:   aload_0
 1:   invokevirtual   #28; //Method foo:()Lscala/Tuple2;
 4:   astore_2
 5:   aload_2
 6:   ifnull  40
 9:   new     #7; //class scala/Tuple2
 12:  dup
 13:  aload_2
 14:  invokevirtual   #32; //Method scala/Tuple2._1:()Ljava/lang/Object;
 17:  aload_2
 18:  invokevirtual   #35; //Method scala/Tuple2._2:()Ljava/lang/Object;
 21:  invokespecial   #20; //Method scala/Tuple2."<init>":(Ljava/lang/Object;Ljava/lang/Object;)V
 24:  astore_1
 25:  aload_1
 26:  invokevirtual   #39; //Method scala/Tuple2._1$mcI$sp:()I
 29:  istore_3
 30:  aload_1
 31:  invokevirtual   #35; //Method scala/Tuple2._2:()Ljava/lang/Object;
 34:  checkcast       #41; //class java/lang/String
 37:  astore  4

这是因为编译器没有检查foo()的返回值是不是元组?

JVM是否会优化结构?

解决方法

这似乎是根据 spec(4.1值声明和定义 – 稍微重新格式化stackoverflow显示):

Value definitions can alternatively have a pattern (§8.1) as left-hand side. If p is some pattern other than a simple name or a name followed by a colon and a type,then the value definition val p = e is expanded as follows:

  1. If the pattern p has bound variables x1,. . .,xn,where n >= 1:
    Here,$x is a fresh name.
val $x = e match {case p => (x1,xn)}
  val x1 = $x._1
  . . .
  val xn = $x._n

因此,元组创建发生在解析器阶段.所以val(i,s)=(1,“s”)在解析器阶段结束时消耗到:

private[this] val x$1 = scala.Tuple2(1,"s"): @scala.unchecked match {    
  case scala.Tuple2((i @ _),(s @ _)) => scala.Tuple2(i,s)
};
val i = x$1._1;
val s = x$1._2

在这个简单的测试上测量这一百万次迭代:

def foo: (Int,String) = (123,"123")
def bar: Unit = { val (i,s) = foo }
def bam: Unit = { val f = foo; val i = f._1; val s = f._2 }

产量

foo: Elapsed: 0.030
bar: Elapsed: 0.051
._1 ._2 access: Elapsed: 0.040

并使用-optimize标志:

foo: Elapsed: 0.027
bar: Elapsed: 0.049
._1 ._2 access: Elapsed: 0.029

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读