【问题标题】:Unnecessary load and store instruction in scala's byte codescala字节码中不必要的加载和存储指令
【发布时间】:2013-10-10 12:51:15
【问题描述】:

我刚刚对模式匹配及其对应的字节码做了一些调查。

val a = Array(1,2,3,4)
a.map {
  case i => i + 1
}

对于上面的代码,我使用 javap 得到了 map 中匿名函数的字节码:

public int apply$mcII$sp(int);
Code:
   0: iload_1       
   1: istore_2      
   2: iload_2       
   3: iconst_1      
   4: iadd          
   5: ireturn       

所以在我看来,在第 0 行我们推送一个 int(参数),然后在第 1 行我们加载 int,在第 2 行我们将它推回......这里的目的是什么?

谢谢!

【问题讨论】:

    标签: scala pattern-matching


    【解决方案1】:

    老兄,试试-optimise

      public int apply$mcII$sp(int);
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=2, args_size=2
             0: iload_1       
             1: iconst_1      
             2: iadd          
             3: ireturn 
    

    使用

    scala> :javap -prv -
    

    然后是类似的东西

    scala> :javap -prv $line4/$read$$iw$$iw$$anonfun$1
    

    【讨论】:

    • @darkjh 古代历史!我的 2.9 别名甚至不运行 javap。我刚刚注意到您的拼写错误调查:当您调查某些事情时,结果与您的预期相反。谢谢你。
    【解决方案2】:

    这不是一个真正的答案,因为我无法弄清楚为什么会发生这种情况。我希望这些观察结果至少会有所帮助:)


    我在 Scala 2.10 中看到以下字节码:

    public int apply$mcII$sp(int);
        Code:
           0: iload_1       ; var1 -> stack
           1: istore_2      ; var2 <- stack
           2: iload_2       ; var2 -> stack
           3: iconst_1      ; 1 -> stack
           4: iadd      
           5: istore_3      ; var3 <- stack
           6: iload_3       ; var3 -> stack
           7: ireturn       ; return <- stack
    

    前两条指令似乎只是将 var1 的值移动到 var2,然后将 var2 作为参数移动到堆栈。在iadd 之后可以观察到相同的情况,其中结果存储在var3 中没有明显的原因,因为ireturn 无论如何都会从堆栈中返回值。

    【讨论】:

      猜你喜欢
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-05
      • 1970-01-01
      • 2013-03-08
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多