gpt4 book ai didi

scala - 如何在反编译的 Scala 代码中识别装箱/拆箱?

转载 作者:行者123 更新时间:2023-12-04 07:44:28 27 4
gpt4 key购买 nike

在对 this question 的公认最佳回复中,有一个明确的解释为什么拳击会发生。

但是,如果我反编译代码(使用 java 反编译器),我看不到 scala.runtime.BoxesRunTime 的使用。此外,如果我分析代码(使用 JProfiler),我看不到 BoxesRunTime 的任何实例。

那么,我如何才能真正看到装箱/拆箱的证据?

最佳答案

在这段代码中:

class Foo[T] {
def bar(i: T) = i
}


object Main {
def main(args: Array[String]) {
val f = new Foo[Int]
f.bar(5)
}
}
bar的调用应该先装箱整数。使用 Scala 2.8.1 编译并使用:
javap -c -l -private -verbose -classpath <dir> Main$

查看为 main 生成的字节码 Main的方法类(class)产量:
public void main(java.lang.String[]);                                                      
...
9: iconst_5
10: invokestatic #24; //Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
13: invokevirtual #28; //Method Foo.bar:(Ljava/lang/Object;)Ljava/lang/Object;
16: pop
17: return
...

您可以看到对 BoxesRunTime 的调用在调用 bar 之前.
BoxesRunTime是一个包含原始类型装箱方法的对象,因此总共应该只有一个实例。这里的技巧是库中的这个特定文件是用 Java 编写的,并且转换是静态方法。由于这个原因,在运行时没有它的任何实例,尽管在 Scala 代码中使用它感觉好像它是一个对象。

您可能应该使用 JProfile 寻找装箱原语(例如 java.lang.Integer),尽管我不确定 JVM 是如何工作的,以及它是否真的可以在运行时重写代码并对其进行优化以避免装箱。据我所知,它不应该应用特化(但我相信 CLR 可以)。有和没有装箱情况的一些微基准测试是另一种确定运行时发生的情况的方法。

编辑:

以上假设类型参数没有用 @specialized 注释。注解。在这种情况下,可以避免装箱/拆箱。标准库中的某些类是专门的。见 this sid .

关于scala - 如何在反编译的 Scala 代码中识别装箱/拆箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4982529/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com