我有一个计算块中花费时间的函数:
import collection.mutable.{Map => MMap}
var timeTotalMap = MMap[String, Long]()
var numMap = MMap[String, Float]()
var averageMsMap = MMap[String, Float]()
def time[T](key: String)(block: =>T): T = {
val start = System.nanoTime()
val res = block
val total = System.nanoTime - start
timeTotalMap(key) = timeTotalMap.getOrElse(key, 0L) + total
numMap(key) = numMap.getOrElse(key, 0f) + 1
averageMsMap(key) = timeTotalMap(key)/1000000000f/numMap(key)
res
}
我正在计算一个函数以及在一个地方调用它的位置。
time("outerpos") { intersectPos(a, b) }
并且函数本身以:
开头def intersectPos(p1: SPosition, p2: SPosition)(implicit unify: Option[Identifier] =None): SPosition
= time("innerpos") {(p1, p2) match {
...
}
当我显示每个键的纳米时间(timeTotalMap
)时,我得到(为隐形添加空格)
outerpos-> 37 870 034 714
innerpos-> 53 647 956
这意味着innerpos的总执行时间比外包的总执行时间小1000。
什么!两者之间有一个因素1000?它说外部呼叫比所有内部功能多花费1000倍?我错过了什么,或者某个地方是否有泄漏鬼魂?更新
当我比较每个块的执行次数(numMap
)时,我发现以下内容:
outerpos -> 362878
innerpos -> 21764
这是矛盾的。即使在其他地方调用intersectPos
,它的调用次数是否应该与外部调用的次数一样大?
修改
如果我将行numMap(key) = numMap.getOrElse(key, 0f) + 1
移到时间函数的顶部,则这些数字大致相等。
答案 0 :(得分:1)
nanoTime
被认为是安全的,但不是很准确。以下是一些好的读物:
Is System.nanoTime() completely useless?
System.currentTimeMillis vs System.nanoTime
基本上,您的测试会受到计时器不准确的影响。解决这个问题的一种方法是在相当长的时间内调用time("outerpos")
(注意JIT编译器优化可能会在某个时刻启动)并仅测量一次开始和结束时间。取平均值并重复time("innerpos")
。这就是我能想到的。仍然不是最好的测试;)