如何在不调用Scala函数的情况下测量其执行时间?
如何在Scala中仅在调用函数时测量其执行时间
你遇到的问题很典型——当前的time函数在你把目标函数传递给它的时候就立刻执行了统计逻辑,而不是等到目标函数被实际调用时才触发。这是因为你直接把函数值传给了time,而time里的block会被立即求值(虽然是call-by-name,但这里的block是一个已经存在的函数值,求值就是返回它本身)。
正确的实现方式:包装目标函数
我们需要修改time函数,让它返回一个新的函数,这个新函数在被调用时才会执行原函数并统计时间。这样只有当你实际调用目标函数时,才会触发耗时统计。
修改后的代码如下:
def time[A, R](f: A => R): A => R = { (a: A) => { val t0 = System.nanoTime() val result = f(a) val t1 = System.nanoTime() println(s"Elapsed time: ${t1 - t0}ns") result } }
测试验证
现在用你的测试代码来验证:
object MapTimeMeasure { def main(args: Array[String]): Unit = { val intToString: Int => String = x => s"$x" // 这里只是包装函数,不会触发统计 val intToString2: Int => String = time(intToString) // 只有调用的时候才会打印耗时 println(intToString2(42)) } }
运行这段代码,你会发现只有在调用intToString2(42)的时候,控制台才会输出耗时记录,完全符合你的需求。
扩展:支持无参数函数
如果需要支持无参数的函数,可以再重载一个版本:
def time[R](f: () => R): () => R = { () => { val t0 = System.nanoTime() val result = f() val t1 = System.nanoTime() println(s"Elapsed time: ${t1 - t0}ns") result } }
使用方式:
val hello = () => "Hello World" val timedHello = time(hello) timedHello() // 此时才会统计时间
内容的提问来源于stack exchange,提问作者Cherry
相关产品推荐
相关产品推荐

