Last active
September 9, 2020 17:07
-
-
Save lawrenceching/46e423dac385f22eceabc639dcbd8493 to your computer and use it in GitHub Desktop.
A util class to measure how much a operation take
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
package me.imlc.example | |
import java.lang.StringBuilder | |
import java.util.* | |
class Tracker { | |
data class Tick(val name:String, val timeInMillis: Long) | |
companion object { | |
private val record = hashMapOf<String, ArrayList<Tick>>() | |
fun start(): String { | |
val uuid = UUID.randomUUID().toString() | |
record[uuid] = arrayListOf() | |
tick(uuid, "start") | |
return uuid | |
} | |
fun tick(id: String, name: String) { | |
record[id]?.add(Tick(name, System.currentTimeMillis())) | |
} | |
fun end(id: String) { | |
tick(id, "end") | |
} | |
fun clear(id: String) { | |
record.remove(id) | |
} | |
fun toFormattedString(id: String): String? { | |
if(record[id] == null) return null | |
val builder = StringBuilder() | |
val list = record[id]!! | |
val maxNameLength = list.map { it.name.length }.maxOrNull() ?: 0 | |
val maxTimeLength = list.map { it.timeInMillis.toString().length }.maxOrNull() ?: 0 | |
val format = "%-${maxNameLength+4}s%${maxTimeLength+4}s%16s%16s" | |
builder.append(String.format(format, "Name", "Time", "Used(ms)", "Passed(ms)")).append(System.lineSeparator()) | |
var t = list.first().timeInMillis | |
val start = t | |
for (tick in list) { | |
builder.append( | |
String.format(format, | |
tick.name, | |
tick.timeInMillis, | |
tick.timeInMillis - t, | |
tick.timeInMillis - start), | |
) | |
.append(System.lineSeparator()) | |
t = tick.timeInMillis | |
} | |
builder.append(System.lineSeparator()) | |
builder.append("Total: ${list.last().timeInMillis - list.first().timeInMillis} ms").append(System.lineSeparator()) | |
return builder.toString() | |
} | |
} | |
} |
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
package me.imlc.example | |
import kotlinx.coroutines.delay | |
import kotlinx.coroutines.runBlocking | |
import org.junit.jupiter.api.Test | |
import java.util.concurrent.CompletableFuture | |
internal class TrackerTest { | |
@Test | |
internal fun toFormattedString() { | |
val id = Tracker.start() | |
runBlocking { | |
Tracker.tick(id, "load configuration") | |
delay(200) | |
Tracker.tick(id, "connect to database") | |
delay(300) | |
Tracker.tick(id, "prepare documentation") | |
delay(400) | |
Tracker.tick(id, "ready for service") | |
} | |
Tracker.end(id) | |
println(Tracker.toFormattedString(id)) | |
/* | |
Name Time Used(ms) Passed(ms) | |
start 1599671093021 0 0 | |
load configuration 1599671093104 83 83 | |
connect to database 1599671093315 211 294 | |
prepare documentation 1599671093617 302 596 | |
ready for service 1599671094018 401 997 | |
end 1599671094019 1 998 | |
Total: 998 | |
*/ | |
} | |
@Test | |
internal fun toFormattedString_MultipleThreads() { | |
val id = Tracker.start() | |
CompletableFuture.completedFuture(null) | |
.thenApply { sleep(); Tracker.tick(id , "Load Cache")} | |
.thenApply { sleep(); Tracker.tick(id , "HTTP GET")} | |
.thenApply { sleep(); Tracker.tick(id , "Write Database")} | |
.thenApply { Tracker.end(id) } | |
.thenApply { println(Tracker.toFormattedString(id)) } | |
.join() | |
} | |
fun sleep() { | |
Thread.sleep(100) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment