Scala是否使用常量返回值优化方法定义?

时间:2015-02-23 06:50:33

标签: scala optimization

Scala是否使用常量返回值优化方法定义到val?

class MyClass extends MyTrait {
  override def getMap(): Map[Int, String] = Map(1 -> "one")
}

trait MyTrait {
  def getMap() : Map[Int, String]
}

优化到?

class MyClass extends MyTrait {
  val getMap: Map[Int, String] = Map(1 -> "one")
}

这样可以让程序员在必要时选择使用动态定义。

2 个答案:

答案 0 :(得分:6)

不,它没有。 valdef有不同的合同,并在语言中产生后果。路径相关类型不能基于def,而def可能会被val覆盖,反之亦然。

具体来说,val返回的值每次初始化时都保证相同,而def每次调用时都会返回不同的值。

考虑到调用文字的情况,可以考虑优化,但在代码中并非如此。 Map(1 -> "one")是一个方法调用,每次都可以返回不同的值(就像def)。

哦,小细节,如果您感兴趣:valdef都是通过方法调用实现的,虽然前者从字段读取,而后者不是。< / p>

答案 1 :(得分:6)

不,它没有。事实上,scalac无法做到这一点。这只能由VM完成,VM在运行时具有有关程序的完整信息。这就是原因。

首先,某些课程SubClass可以使用其他方法扩展MyClass并覆盖getMap。如果scalac确实实现了此优化,则SubClass将从其超类中获得一个空虚假字段,并增加占用空间。

其次,scalac不知道如何实施Map。如果Map工厂有副作用,则此优化会阻止每次调用getMap时执行。这改变了程序的语义。有一些early attempts to overcome this,并保留更多信息供编译器分析,但你应该知道,这样的优化仍然可能会破坏依赖注入和模拟框架所依赖的反射特性。

最后,目前尚不清楚这何时是真正的优化。如果返回表达式真的很便宜(例如一个数字),它会增加类的内存占用,以缓存一个几乎不费力就可以计算的值。

顺便说一下,你所描述的不是静态函数定义,而是具有常量返回值的方法定义