Skip to content

Instantly share code, notes, and snippets.

@ilaborie
Last active March 2, 2020 12:38
Show Gist options
  • Save ilaborie/1f912f8b880bcf493974ce92221cd052 to your computer and use it in GitHub Desktop.
Save ilaborie/1f912f8b880bcf493974ce92221cd052 to your computer and use it in GitHub Desktop.
Duration utils in Kotlin
val Int.nano: Duration
get() = ofNanos(this.toLong())
val Int.nanos: Duration
get() = ofNanos(this.toLong())
val Long.nano: Duration
get() = ofNanos(this)
val Long.nanos: Duration
get() = ofNanos(this)
val Int.milli: Duration
get() = ofMillis(this.toLong())
val Int.millis: Duration
get() = ofMillis(this.toLong())
val Long.milli: Duration
get() = ofMillis(this)
val Long.millis: Duration
get() = ofMillis(this)
val Int.second: Duration
get() = ofSeconds(this.toLong())
val Int.seconds: Duration
get() = ofSeconds(this.toLong())
val Long.second: Duration
get() = ofSeconds(this)
val Long.seconds: Duration
get() = ofSeconds(this)
val Int.minute: Duration
get() = ofMinutes(this.toLong())
val Int.minutes: Duration
get() = ofMinutes(this.toLong())
val Long.minute: Duration
get() = ofMinutes(this)
val Long.minutes: Duration
get() = ofMinutes(this)
private val unitLabels = listOf(
NANOS to "ns",
MICROS to "µs",
MILLIS to "ms",
SECONDS to "s",
MINUTES to "min",
HOURS to "h",
DAYS to " days",
MONTHS to " months",
YEARS to " years",
CENTURIES to " centuries",
FOREVER to " ∞"
)
fun Duration.humanize(depth: Int = 2): String {
require(depth > 0) { "Require a depth strictly positive" }
tailrec fun aux(depth: Int, duration: Duration, acc: String): String =
if (depth == 0 || duration.isZero) acc
else {
val (tu, unit) = unitLabels.lastOrNull() { (tu, _) ->
tu.duration < duration
} ?: unitLabels.last()
val value = duration.toNanos() / tu.duration.toNanos()
val rest = duration.toNanos() % tu.duration.toNanos()
aux(depth - 1, ofNanos(rest), if (acc.isEmpty()) "$value$unit" else "$acc $value$unit")
}
return aux(depth, this, "")
}
inline fun <T> elapsed(consumer: (Duration) -> Unit = { println("Took ${it.humanize()}") }, block: () -> T): T {
val start = System.nanoTime()
try {
return block()
} finally {
val duration = ofNanos(System.nanoTime() - start)
consumer(duration)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment