scala编译器会提升正则表达式吗?

时间:2014-09-26 08:39:02

标签: scala optimization hoisting

我想知道是否:

object Foo {
  val regex = "some complex regex".r
  def foo() {
    // use regex
  }
}

和此:

object Foo {
  def foo() {
    val regex = "some complex regex".r
    // use regex
  }
}

会有任何性能差异。即,scala编译器会识别"some complex regex".r是一个常量并缓存它,以便它不会每次都重新编译吗?

1 个答案:

答案 0 :(得分:6)

它在运行时会有所不同。第一个例子的表达式只计算一次。从第二个表达式 - 每次调用Foo.foo()时。这里的计算意味着将隐式添加的函数“r”(来自scala-library)应用于字符串:

scala> ".*".r
res40: scala.util.matching.Regex = .*

这个函数实际上在每次调用时编译正则表达式(没有缓存)。

顺便说一下,运行时对正则表达式的任何天真缓存容易受OutOfMemory的影响 - 但是,我相信可以使用WeakHashMap安全地实现它,但是当前Java的Pattern实现(这是scala的Regexdoesn't的基础实际实现它,可能是因为这样的实现可能对性能没有可预测的影响(GC可能必须在每次运行时删除大多数缓存值)。带有驱逐的缓存更容易预测,但仍然不是那么简单(谁会为它选择超时/大小?)。谈到scala-way,一些智能宏可以在编译时进行优化(仅针对'基于字符串常量'的regexp进行缓存),但默认情况下:

Scala编译器也没有关于regexp的任何优化,因为regexp不是scala语言的一部分。

因此最好将静态“”.r结构移出函数。