gpt4 book ai didi

Scala:编译器可以有效地优化常量吗?

转载 作者:行者123 更新时间:2023-12-03 16:09:00 25 4
gpt4 key购买 nike

让我们考虑以下几点:

object Foo {
val BUFFER_SIZE = 1024
}

class Foo {
.
.
.

val buffer = new Array[Byte](Foo.BUFFER_SIZE)

这太冗长了,与Java的静态(最终)变量相比似乎并不优雅,尤其是因为常量的定义和用法相距太远,无法立即理解代码。我想要的是这样的:
class Foo {
val BUFFER_SIZE = 1024

val buffer = new Array[Byte](BUFFER_SIZE)

问题是,Scala 编译器是否足够智能,不会为每个 Foo 实例实例化 BUFFER_SIZE 以浪费时间和空间?还是应该用第一个?

最佳答案

TLDR:不,它不是那么好,但你可以引导编译器。

而且很容易检查(我把代码放到 test.scala 中):

scalac test.scala 
javap Foo.class
// Compiled from "test.scala"
// public class Foo {
// public int BUFFER_SIZE();
// public byte[] buffer();
// public Foo();
// }

所以 val 最终成为一个 getter 方法。现在让我们看看实际的字节码:
javap -c Foo.class
Compiled from "test.scala"
public class Foo {
public int BUFFER_SIZE();
Code:
0: aload_0
1: getfield #15 // Field BUFFER_SIZE:I
4: ireturn

// .... irrelevant parts

如您所见,有一个 getfield代码意味着每个类实例都有不同的实例(与 getstatic 相比,这意味着访问静态变量)。
高度优化的代码看起来像
public final int BUFFER_SIZE();
Code:
0: sipush 1024
3: ireturn

如果你用 final 标记 BUFFER_SIZE 将会产生修饰符:
class Foo {
final val BUFFER_SIZE = 1024

val buffer = new Array[Byte](BUFFER_SIZE)
}

private[this] 前缀字段正如@ghik 所说的那样也能解决问题。不同的是 final使用简单的代码生成 getter,而 private[this]直接内联值。

关于Scala:编译器可以有效地优化常量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19189572/

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