Skip to content

Instantly share code, notes, and snippets.

@makiftutuncu
Last active August 24, 2016 07:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save makiftutuncu/a2836a36bec4421957b2a47b9974a35e to your computer and use it in GitHub Desktop.
Save makiftutuncu/a2836a36bec4421957b2a47b9974a35e to your computer and use it in GitHub Desktop.
A simple, straightforward timer implementation backed by Java 8 time APIs
import java.time.{Duration, Instant}
import java.util.UUID
import java.util.concurrent.atomic.AtomicReference
import java.util.function.UnaryOperator
object Timer {
private val map: AtomicReference[Map[String, Instant]] = new AtomicReference[Map[String, Instant]](Map.empty[String, Instant])
def start(key: String): Instant = {
val now: Instant = Instant.now
val previousInstantAsOpt: Option[Instant] = map.get().get(key)
if (previousInstantAsOpt.isDefined) {
println(s"""There was already a timer started for key "$key". It will be overridden!""")
}
map.getAndUpdate(new UnaryOperator[Map[String, Instant]] {
override def apply(m: Map[String, Instant]): Map[String, Instant] = {
m + (key -> now)
}
})
now
}
def stop(key: String): Duration = {
val now: Instant = Instant.now
val previousInstantAsOpt: Option[Instant] = map.get().get(key)
if (previousInstantAsOpt.isEmpty) {
println(s"""There no timer started for key "$key". It might have already been stopped!""")
Duration.ofMillis(0)
} else {
map.getAndUpdate(new UnaryOperator[Map[String, Instant]] {
override def apply(m: Map[String, Instant]): Map[String, Instant] = {
m - key
}
})
Duration.ofMillis(now.toEpochMilli - previousInstantAsOpt.get.toEpochMilli)
}
}
def time[R](action: => R): (Duration, R) = {
val key: String = UUID.randomUUID().toString
start(key)
val result: R = action
val duration: Duration = stop(key)
duration -> result
}
}
object Test {
def doLongRunningOperation1(): Unit = {
// Bla bla bla
}
def doLongRunningOperation2(): String = {
// Bla bla bla
""
}
def main(args: Array[String]): Unit = {
val operation1Start: Instant = Timer.start("operation1")
doLongRunningOperation1()
val operation1Duration: Duration = Timer.stop("operation1")
println(s"Operation 1 started at $operation1Start and took ${operation1Duration.toMillis} ms.")
val (operation2Duration: Duration, result: String) = Timer.time {
doLongRunningOperation2()
}
println(s"Operation 2 took ${operation2Duration.toMillis} ms.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment