截至 2014 年 1 月
当前的基准测试大约有 3 年的历史,Hotspot 和编译器已经有了很大的发展。我也在使用Google Caliper 来执行基准测试。
代码
import com.google.caliper.SimpleBenchmark
class Benchmark extends SimpleBenchmark {
def timeRaw(reps: Int) = {
var i = 0
var result = 0L
while (i < reps) {
result += 0xc37e ^ (i * 0xd5f3)
i = i + 1
}
result
}
def normal(i: Int): Long = 0xc37e ^ (i * 0xd5f3)
def timeNormal(reps: Int) = {
var i = 0
var result = 0L
while (i < reps) {
result += normal(i)
i = i + 1
}
result
}
def timeInner(reps: Int) = {
def inner(i: Int): Long = 0xc37e ^ (i * 0xd5f3)
var i = 0
var result = 0L
while (i < reps) {
result += inner(i)
i = i + 1
}
result
}
def timeClosure(reps: Int) = {
var i = 0
var result = 0L
val closure = () => result += 0xc37e ^ (i * 0xd5f3)
while (i < reps) {
closure()
i = i + 1
}
result
}
def normal(i: Int, j: Int, k: Int, l: Int): Long = i ^ j ^ k ^ l
def timeUnboxed(reps: Int) = {
var i = 0
var result = 0L
while (i < reps) {
result += normal(i,i,i,i)
i = i + 1
}
result
}
val closure = (i: Int, j: Int, k: Int, l: Int) => (i ^ j ^ k ^ l).toLong
def timeBoxed(reps: Int) = {
var i = 0
var result = 0L
while (i < reps) {
closure(i,i,i,i)
i = i + 1
}
result
}
}
结果
benchmark ns linear runtime
Normal 0.576 =
Raw 0.576 =
Inner 0.576 =
Closure 0.532 =
Unboxed 0.893 =
Boxed 15.210 ==============================
非常令人惊讶的是,闭包测试的完成速度比其他测试快了大约 4ns。这似乎是 Hotspot 而不是执行环境的特性,多次运行返回了相同的趋势。
使用执行装箱的闭包会对性能造成巨大影响,执行一次拆箱和重新装箱大约需要 3.579ns,足以进行大量原始数学运算。在这个特定的职位上,在new optimizer 上完成的工作可能会变得更好。在一般情况下,miniboxing 可能会缓解拳击。
编辑:
新的优化器在这里并没有真正的帮助,它使 Closure 慢 0.1 ns 和 Boxed 快 0.1 ns:
benchmark ns linear runtime
Raw 0.574 =
Normal 0.576 =
Inner 0.575 =
Closure 0.645 =
Unboxed 0.889 =
Boxed 15.107 ==============================
使用来自 magarciaEPFL/scala 的 2.11.0-20131209-220002-9587726041 执行
版本
JVM
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)
标量
Scala compiler version 2.10.3 -- Copyright 2002-2013, LAMP/EPFL