更快地实现Option.isEmpty?

时间:2015-02-04 18:32:50

标签: performance scala

isEmptyOption的实施很简单 - 这是一个草图:

abstract class Option[+A]           { def isEmpty:Boolean  }
object None extends Option[Nothing] { def isEmpty=true }
final class Some extends Option[+A] { def isEmpty=false }

isEmpty被极度使用,包括Option本身,所以它的性能很重要,即使它是如此微不足道。

我怀疑实施它会更快:

abstract class Option[+A] { final def isEmpty = this eq None  }

此实现不应该要求取消引用该选项或调用其上的任何方法,AFAIK - 只是一个简单的参考比较。

我对此进行了性能测试,但是JVM微基准测试非常棘手,我对创建有意义的结果的能力毫无信心。

我有什么因素可以忽略吗?

2 个答案:

答案 0 :(得分:4)

(基于Eugenes Zhulenev的评论)

似乎HotSpot编译器会自动执行此优化,因为Option只有两个子类:

Polymorphism Performance Mysteries Explained

  

根据Cliff Click,服务器HotSpot编译器将双态作为多态性的一个特例来处理:"服务器编译器只能证明两个类到达一个调用站点,它将插入一个类型-check然后静态调用两个目标(然后可以进一步内联等)。"

答案 1 :(得分:4)

实际上,可能是正确的。使用以下代码:

sealed abstract class Opshun[+A] {
  final def isEmpty = this eq Nun
  def get: A 
}
object Nun extends Opshun[Nothing] { def get = ??? }
case class Summ[+A](get: A) extends Opshun[A] {}

关于最简单的测试用例(OptionOpshun的数组),如果您只是测试isEmpty,那么您建议的模式是5倍(!)更快,而您如果您使用.isEmpty手动替换eq None或选择None模式匹配,则可以验证这一点。

如果你转向一个更复杂的情况,你不测试 - isEmpty然后得到一个存储值,那么差异就不那么令人印象深刻了(快三分之一)。

所以这个建议有价值;它值得在更官方的环境中进行测试。

注意在编辑中添加:这是使用足够大的数组,以便不是所有内容都适合L2缓存。当它适合L2时,两种方式都同样快。