Last active
August 24, 2016 07:01
-
-
Save makiftutuncu/a2836a36bec4421957b2a47b9974a35e to your computer and use it in GitHub Desktop.
A simple, straightforward timer implementation backed by Java 8 time APIs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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