I have a scala code running multiple futures at once. I want to profile the time spent executing each of them. For example:
for (i <- 1 to 100) {
val f = future { runAndTime(doSomething()) }
f.onComplete {
case Success(timeTaken) => println(timeTaken)
case Failure(t) => println(t.getMessage())
}
}
A naive implementation of runAndTime
could be:
def runAndTime(func: => Unit) = {
var time = System.currentTimeMillis()
func
System.currentTimeMillis() - time
}
The problem with this runAndTime
is that when the thread isn't executing (for e.g. if in the middle of func it was dequeued from the cpu and some other thread started running) the system is still elapsing time, so we don't get time spent in that particular thread but overall time difference between thread-start and thread-end.
How can I write a runAndTime
which will count the time the future is actually executing in CPU?
You can use the ThreadMXBean
to get the accumulated time that the current thread has spent on the CPU, just like currentTimeMillis
(more like nanos) but accounting for cpu scheduling. It's not guaranteed to be on all JVM's but most standard implementations have access to this (I think it throws if unavailable).
import java.lang.management.ManagementFactory
def runAndTime(f: => Unit) = {
val start = ManagementFactory.getThreadMXBean.getCurrentThreadCpuTime
f
ManagementFactory.getThreadMXBean.getCurrentThreadCpuTime - start
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With