// function type is A (e.g. String)
sclass FunctionTimings {
Map data = syncMap();
void doCtex aka timeCtex(A function, RunnableWithExceptions r) ctex {
if (r == null) ret;
long time = nanoTime();
try {
r.run();
} finally {
time = nanoTime()-time;
saveTiming(function, time);
}
}
B get(A function, IF0 f) {
if (f == null) null;
new Var var;
time(function, -> var.set(f!));
ret var!;
}
void do aka time(A function, Runnable r) {
if (r == null) ret;
long time = nanoTime();
try {
r.run();
} finally {
time = nanoTime()-time;
saveTiming(function, time);
}
}
void saveTiming(A function, long time) {
Average avg = syncMapGetOrCreate(data, function, -> new Average);
avg.add(time);
}
Map get() { ret cloneMap(data); }
void reset aka clear() { data.clear(); }
// as multi-line string, sorted alphabetically
public S render aka toString() {
ret lines(renderedEntries());
}
LS renderedEntries() {
ret ciSorted(map(get(), (f, avg) ->
functionToString(f) + ": " + n2(iround(nsToMicroseconds(avg!)))
+ " " + microSymbol() + "s (" + n2(iround(avg.n())) + ")"));
}
S toStringSingleLine() {
ret joinWithComma(renderedEntries());
}
S functionToString(A f) {
ret firstToUpper(str(f));
}
}