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

lyo*_*omi 5 optimization scala hoisting

我想知道这是否:

object Foo {
  val regex = "some complex regex".r
  def foo() {
    // use regex
  }
}
Run Code Online (Sandbox Code Playgroud)

还有这个:

object Foo {
  def foo() {
    val regex = "some complex regex".r
    // use regex
  }
}
Run Code Online (Sandbox Code Playgroud)

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

dk1*_*k14 6

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

scala> ".*".r
res40: scala.util.matching.Regex = .*
Run Code Online (Sandbox Code Playgroud)

每次调用它时,此函数实际上都会编译正则表达式(无缓存).

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

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

所以最好将静态的".r"结构移出函数.