Nic Foster
Nic Foster

Reputation: 2894

Can scope timers be made in Scala?

I'm trying to make a timer that measures the execution time of a scope. I could do this by starting a timer manually, and then putting something at the end of a scope to stop the timer, but that's twice as much work. In C++ you can create a timer class that evaluates when its destructor is called, and destructors are called when something goes out of scope, so the timer takes care of itself "automagically". With Scala being a managed language, an instance won't disappear until it is garbage collection, so relying on that method is essentially useless in terms of a timer, unless I was trying to time how long something lived until it was garbage collected.

Here's an example of what the code for making a timer would look like if it auto-evaluated at the time it left scope:

def someMethod(someVar: Int) {
  val myTimer: ScopeTimer = ScopeTimer(startImmediately = true)

  // Do some stuff

  // Do more stuff

  10   // Return some int value here
}

As the method returned 10, myTimer would leave scope, and fire.

Is there any easy way of making a timer to evaluate the execution time of a scope like this, in Scala?

Upvotes: 2

Views: 215

Answers (1)

Alan Burlison
Alan Burlison

Reputation: 1062

How about something like this:

scala> :paste
// Entering paste mode (ctrl-D to finish)

def timedScope(op: => Unit): Long = {
  val start = System.nanoTime
  op
  System.nanoTime - start
}
^D
// Exiting paste mode, now interpreting.

timedScope: (op: => Unit)Long

scala> timedScope { Thread.sleep(5000) }
res2: Long = 5010040127

scala> 

The parameter 'op' is being passed as a by-name parameter to timedScope so it isn't evaluated until it is used inside the body of timedScope.

And to answer your followup question about calling from an object, it works just fine:

scala> object Bar { def doBar = { timedScope { Thread.sleep(5000) } } }
defined module Bar

scala> Bar.doBar
res18: Long = 5010033226

Upvotes: 11

Related Questions