如何以聚合方式对 Scala 地图功能进行计时?
How to time scala map functions in an aggregative fashion?
我很难想出一个解决方案来为 Scala 映射操作中的各个函数计时。假设我的代码中有以下行:
val foo = data.map(d => func1(d).func2())
其中 data
是 N 个元素的序列。我将如何计算我的程序总共执行 func1
和 func2
的时间?由于是map操作,这些函数会被调用N次,所以每次记录都要加到一个累计时间记录中。
如何在不破坏 Scala 语法的情况下执行此操作?
注意:我想以 totalTime_inFunc1
和 totalTime_inFunc2
结束。
看看Closure。您将声明您的函数并使它们引用作用域中的变量,然后将它们传递给映射,并使它们从作用域中递增变量。
编辑
带闭包的代码
object closure {
var time1 = 0L
var time2 = 0L
def time[R](block: => R)(time: Int): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
if (time==1)
time1 += t1-t0
else
time2 += t1-t0
result
}
def fun1(i: Int): Int = {
time{i+1}(1)
}
def fun2(i: Int): Int = {
time{i+2}(2)
}
}
val data = List(1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7)
val foo = data.map(d => closure.fun2(closure.fun1(d)))
closure.time1 // res4: Long = 22976
closure.time2 // res5: Long = 25438
编辑 2
object closure {
var time1 = 0L
var time2 = 0L
def time[R](block: => R)(time: Int): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
if (time==1)
time1 += t1-t0
else
time2 += t1-t0
result
}
val data = List(1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7)
val test = new test;
val foo = data.map(d => {
val fun1 = time{test.fun1(d)}(1)
time{fun1.fun2(d)}(2)
})
}
val s = Seq(1, 2, 3)
val (mappedSeq, totalTime) = s.map(x => {
// call your map methods here and time
// x is the mapped element
val timing = 5.5
// then return the tuple with mapped element and time taken for the map function
(x, timing)
}).foldLeft((Seq.empty[Int], 0d))((accumulator, pair) => (accumulator._1 :+ pair._1, accumulator._2 + pair._2))
println(totalTime)
println(mappedSeq.mkString(", "))
比方说,func2()
returns YourType
。然后,你需要从 map
中的函数 return 元组 (YourType, Long, Long)
,其中第二个元组元素是 func1 的执行时间,第三个元素是 func2 的执行时间。之后,您可以使用 sum:
轻松地从元组序列中获取执行时间
val fooWithTime = {
data.map(d => {
def now = System.currentTimeMillis
val beforeFunc1 = now
val func1Result = func1(d)
val func1Time = now - beforeFunc1
val beforeFun2 = now
val result = func1Result.func2()
(result, func1Time, now - beforeFun2)
}
}
val foo = fooWithTime.map(_._1)
val totalTimeFunc1 = fooWithTime.map(_._2).sum
val totalTimeFunc2 = fooWithTime.map(_._3).sum
此外,您可以轻松地使用您喜欢的计算执行时间的方法而不是 System.currentTimeMillis()
。
我很难想出一个解决方案来为 Scala 映射操作中的各个函数计时。假设我的代码中有以下行:
val foo = data.map(d => func1(d).func2())
其中 data
是 N 个元素的序列。我将如何计算我的程序总共执行 func1
和 func2
的时间?由于是map操作,这些函数会被调用N次,所以每次记录都要加到一个累计时间记录中。
如何在不破坏 Scala 语法的情况下执行此操作?
注意:我想以 totalTime_inFunc1
和 totalTime_inFunc2
结束。
看看Closure。您将声明您的函数并使它们引用作用域中的变量,然后将它们传递给映射,并使它们从作用域中递增变量。
编辑
带闭包的代码
object closure {
var time1 = 0L
var time2 = 0L
def time[R](block: => R)(time: Int): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
if (time==1)
time1 += t1-t0
else
time2 += t1-t0
result
}
def fun1(i: Int): Int = {
time{i+1}(1)
}
def fun2(i: Int): Int = {
time{i+2}(2)
}
}
val data = List(1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7)
val foo = data.map(d => closure.fun2(closure.fun1(d)))
closure.time1 // res4: Long = 22976
closure.time2 // res5: Long = 25438
编辑 2
object closure {
var time1 = 0L
var time2 = 0L
def time[R](block: => R)(time: Int): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
if (time==1)
time1 += t1-t0
else
time2 += t1-t0
result
}
val data = List(1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7)
val test = new test;
val foo = data.map(d => {
val fun1 = time{test.fun1(d)}(1)
time{fun1.fun2(d)}(2)
})
}
val s = Seq(1, 2, 3)
val (mappedSeq, totalTime) = s.map(x => {
// call your map methods here and time
// x is the mapped element
val timing = 5.5
// then return the tuple with mapped element and time taken for the map function
(x, timing)
}).foldLeft((Seq.empty[Int], 0d))((accumulator, pair) => (accumulator._1 :+ pair._1, accumulator._2 + pair._2))
println(totalTime)
println(mappedSeq.mkString(", "))
比方说,func2()
returns YourType
。然后,你需要从 map
中的函数 return 元组 (YourType, Long, Long)
,其中第二个元组元素是 func1 的执行时间,第三个元素是 func2 的执行时间。之后,您可以使用 sum:
val fooWithTime = {
data.map(d => {
def now = System.currentTimeMillis
val beforeFunc1 = now
val func1Result = func1(d)
val func1Time = now - beforeFunc1
val beforeFun2 = now
val result = func1Result.func2()
(result, func1Time, now - beforeFun2)
}
}
val foo = fooWithTime.map(_._1)
val totalTimeFunc1 = fooWithTime.map(_._2).sum
val totalTimeFunc2 = fooWithTime.map(_._3).sum
此外,您可以轻松地使用您喜欢的计算执行时间的方法而不是 System.currentTimeMillis()
。