gpt4 book ai didi

scala - Scala 中隐式对象包装器的开销

转载 作者:行者123 更新时间:2023-12-01 22:34:06 27 4
gpt4 key购买 nike

考虑以下非常简单的代码:

class A(val a: String, val b: Int)
object Test {
implicit class wrap(obj: A) {
def fn = obj.a + obj.b
}

def main(args: Array[String]) =
println(new A("Hello", 1).fn)
}

反汇编代码得到:

public void main(java.lang.String[]);
Code:
0: getstatic #29; //Field scala/Predef$.MODULE$:Lscala/Predef$;
3: aload_0
4: new #31; //class A
7: dup
8: ldc #33; //String Hello
10: iconst_1
11: invokespecial #36; //Method A."<init>":(Ljava/lang/String;I)V
14: invokevirtual #38; //Method wrap:(LA;)LTest$wrap;
17: invokevirtual #42; //Method Test$wrap.fn:()Ljava/lang/String;
20: invokevirtual #46; //Method scala/Predef$.println:(Ljava/lang/Object;)V
23: return

编译器在隐式使用 fn 时有效地创建包装对象。

虽然我很清楚 JIT 编译可以消除这个问题,但过早的优化是不好的,而且我的大多数代码不太可能遇到任何性能问题,但在幕后创建静态函数并不会编译器似乎不需要做很多工作,并且可以消除这个问题。

所以,我只是好奇:Scala 团队决定不包含此优化有什么特殊原因吗?

最佳答案

在这种情况下,无法判断您是否要将 A 用作普通类,或者是否打算将其用作隐式包装器。对于简单包装类型的类,您可以利用值类,这些值类应该将糖化为您想要的行为(也称为无包装类),只需使用第一个参数作为包装值的方法调用即可。不幸的是,它们仅适用于构造函数为一的类。

 object Test {
implicit class A(val a: String) extends AnyVal {
def foo: String = a
}

def main(args: Array[String]) {
"Hello World!".foo
}
}

这会产生副作用,因为这样的代码通常会编译成模块加载,然后调用invokevirtual。这可以进行优化,Miguel Garcia 正在努力将此类情况变成 "really static" .

关于scala - Scala 中隐式对象包装器的开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16286049/

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