This is fairly simple, so I'm just looking for ideas on anything that can be cleaned up, places it can be extended, and suggestions regarding style/naming (I'm terrible at naming).
It allows you to write something like:
object TimerTest extends App {
import Timers._
val time: Long = TimeBlock { timer =>
println("Starting...")
println(timer.interTime)
val s = (0 to 500000).foldRight(0)(_+_)
println(timer.interTime)
val s2 = (0 to 100000).foldRight(0)(_*_)
println(timer.interTime)
val s3 = (0 to 100000).foldRight(0)((x, y) => x + y * y + x)
}
println("Final Time: " + time)
}
Timer.scala:
object Timers {
case class Timer(startTime: Long = new Date().getTime) {
private def curMs: Long = new Date().getTime
//Shortcut to start a new timer using a previous one
def restart: Timer = Timer(curMs)
//Doesn't actually stop it, because it's immutable
// Returns the amount of time since the Timer was started
def stop: Long = curMs - startTime
//To be used in a TimeBlock to get an intermediate time
def interTime: Long = stop
//Same as stop, but also returns a new Timer that starts where the
// previous one ended
def lap: (Long, Timer) = { val curTime = curMs
(curTime - startTime, Timer(curTime))
}
}
//Convenience class to help manage starting/stopping
// It supplies the internal timer to check intermediate times
// within the block
case class TimeBlock(body: Timer => Unit) {
val t = Timer()
body(t)
def stop = t.stop
}
//Same as the other TimeBlock, but simpler
// Doesn't supply the timer, so you can't check intermediate times
class SimpleTimeBlock(body: => Unit) {
val t = Timer()
body
def stop: Long = t.stop
}
object SimpleTimeBlock {
def apply[A](body: => A) =
new SimpleTimeBlock(body)
}
//Implicits to auto-stop TimeBlocks so they return the elapsed time
implicit def StopLooseTimeBlocks(tB: TimeBlock): Long =
tB.stop
implicit def StopLooseSTimeBlocks(tB: SimpleTimeBlock): Long =
tB.stop
}