Skip to content

Instantly share code, notes, and snippets.

@apatrida
Created September 20, 2014 17:04
Show Gist options
  • Save apatrida/a496cc60416c01044628 to your computer and use it in GitHub Desktop.
Save apatrida/a496cc60416c01044628 to your computer and use it in GitHub Desktop.
More with expressive Time things and Kotlin
enum class TimeUnit(val name: String, val divisorFromNanos: Long, val precision: Int) {
Seconds : TimeUnit("seconds", 1000000000, 2)
Millis : TimeUnit("millis", 1000000, 0)
Micros : TimeUnit("micros", 1000, 0)
Nanos : TimeUnit("nanos", 1, 0)
fun toHumanReadable(nanoTime: Long): String = "%.${precision}f ${name}".format(nanoTime.toFloat() / divisorFromNanos.toFloat())
}
class Duration(val duration: Long, val units: TimeUnit, private val durationInNanos: Long = duration * units.divisorFromNanos) : Comparable<Duration> {
override fun toString(): String = units.toHumanReadable(durationInNanos)
override fun equals(other: Any?): Boolean = other != null && other is Duration && this.durationInNanos == other.durationInNanos
override fun compareTo(other: Duration): Int = this.durationInNanos.compareTo(other.durationInNanos)
override fun hashCode(): Int = (durationInNanos % 0xFFFFFFFF).toInt()
fun to(units: TimeUnit): Duration = Duration(durationInNanos / units.divisorFromNanos, units, durationInNanos)
fun elapsedSince(other: Duration): Duration = Duration(durationInNanos - other.durationInNanos, units)
}
val Int.seconds: Duration get() { return Duration(this.toLong(), TimeUnit.Seconds) }
val Int.nanos: Duration get() { return Duration(this.toLong(), TimeUnit.Nanos) }
val Int.micros: Duration get() { return Duration(this.toLong(), TimeUnit.Micros) }
val Int.millis: Duration get() { return Duration(this.toLong(), TimeUnit.Millis) }
val Long.seconds: Duration get() { return Duration(this, TimeUnit.Seconds) }
val Long.nanos: Duration get() { return Duration(this, TimeUnit.Nanos) }
val Long.micros: Duration get() { return Duration(this, TimeUnit.Micros) }
val Long.millis: Duration get() { return Duration(this, TimeUnit.Millis) }
fun measure(name: String = "timer", desiredUnits: TimeUnit, foo: () -> Unit): Duration {
val startTime = System.nanoTime().nanos
foo()
val endTime = System.nanoTime().nanos
return endTime elapsedSince startTime to desiredUnits
}
// NOW TEST WITH:
fun main(args: Array<String>) {
val elapsed = measure("hello printer", TimeUnit.Nanos) { for (i in 1..1000) println("hello") }
println(elapsed.to(TimeUnit.Seconds))
println(elapsed to TimeUnit.Millis)
println(elapsed to TimeUnit.Micros)
println(elapsed to TimeUnit.Nanos)
println(elapsed to TimeUnit.Millis to TimeUnit.Seconds to TimeUnit.Micros to TimeUnit.Nanos) // lossless
/* output:
0.03 seconds
29 millis
28903 micros
28903000 nanos
28903000 nanos
*/
println(50.seconds)
println(50.millis to TimeUnit.Seconds)
println(1.nanos to TimeUnit.Seconds to TimeUnit.Nanos) // lossless
/* output:
50.00 seconds
0.05 seconds
1 nanos
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment