我要衡量一些代码的性能。 为此,我介绍了以下方法:
def timed[T](body: => T) = {
val start = System.currentTimeMillis
blackHole = body
val end = System.currentTimeMillis
end - start
}
引入blackHole
变量以保留body
结果。这样做是为了防止JVM消除死代码。
在某些书中,有一条声明blackHole
应声明如下:
@volatile
var blackHole: Any = _
为什么要标记变量volatile
?
答案 0 :(得分:2)
当您运行代码很长一段时间后,您将为关键代码部分调用Just In Time编译器(JIT)。它会尝试执行一些优化。
消除死代码。代码没有可观察到的副作用,可以将其删除。
通过将结果分配给实例变量,您可以更难以证明该值为“未使用”。可能来自另一个类/线程的某个人可以在以后使用该值。
在我的基准测试中,易失性部分并不是必需的。我读到的其中一个博客提到JIT可以删除没有它的变量(link)。
答案 1 :(得分:0)
原因是没有volatile,代码就像没有赋值一样死了。当您写入非易失性变量时,访问该变量的其他线程无法保证该操作的结果。所以,只要你没有在同一个帖子中读回结果,就外部世界而言,写作从未发生过。