【发布时间】:2016-08-31 04:02:39
【问题描述】:
我有一个用 Scala 编写的程序。我想测量不同独立代码块的执行时间。当我以明显的方式执行此操作时(即在每个块之前和之后插入System.nanoTime()),我观察到执行时间取决于块的顺序。最初的一些块总是比其他块花费更多的时间。
我创建了一个重现此行为的简约示例。为简单起见,所有代码块都相同,并为整数数组调用 hashCode()。
package experiments
import scala.util.Random
/**
* Measuring execution time of a code block
*
* Minimalistic example
*/
object CodeBlockMeasurement {
def main(args: Array[String]): Unit = {
val numRecords = args(0).toInt
// number of independent measurements
val iterations = args(1).toInt
// Changes results a little bit, but not too much
// val records2 = Array.fill[Int](1)(0)
// records2.foreach(x => {})
for (_ <- 1 to iterations) {
measure(numRecords)
}
}
def measure(numRecords: Int): Unit = {
// using a new array every time
val records = Array.fill[Int](numRecords)(new Random().nextInt())
// block of code to be measured
def doSomething(): Unit = {
records.foreach(k => k.hashCode())
}
// measure execution time of the code-block
elapsedTime(doSomething(), "HashCodeExperiment")
}
def elapsedTime(block: => Unit, name: String): Unit = {
val t0 = System.nanoTime()
val result = block
val t1 = System.nanoTime()
// print out elapsed time in milliseconds
println(s"$name took ${(t1 - t0).toDouble / 1000000} ms")
}
}
使用numRecords = 100000 和iterations = 10 运行程序后,我的控制台如下所示:
HashCodeExperiment 耗时 14.630283 毫秒
HashCodeExperiment 耗时 7.125693 毫秒
HashCodeExperiment 耗时 0.368151 毫秒
HashCodeExperiment 耗时 0.431628 毫秒
HashCodeExperiment 耗时 0.086455 毫秒
HashCodeExperiment 耗时 0.056458 毫秒
HashCodeExperiment 耗时 0.055138 毫秒
HashCodeExperiment 耗时 0.062997 毫秒
HashCodeExperiment 耗时 0.063736 毫秒
HashCodeExperiment 耗时 0.056682 毫秒
有人可以解释这是为什么吗?不应该都一样吗?真正的执行时间是多少?
非常感谢,
彼得
环境参数:
操作系统:ubuntu 14.04 LTS(64 位)
IDE:IntelliJ IDEA 2016.1.1 (IU-145.597)
Scala:2.11.7
【问题讨论】:
-
可靠地对 GCed 语言进行基准测试并不容易 - 对 GCed 和 JITed 语言进行基准测试更加困难。我想说你在前几次迭代中看到的是 JIT 和 JVM 运行时在工作。
标签: scala jvm measurement