ecko profile
Run a program and report where its time went, per function.
ecko profile app.ecko
function calls self ms total ms
--------------------------------------------
normalise 60000 21.02 21.02
parse_row 20000 15.88 36.90
41.10 ms total, 4.20 ms outside any function
The two time columns
self is the one to read first, and the report is sorted by it. It is the time spent inside the function itself, with everything it called taken out, so it points at the code that is actually slow rather than at whatever sits at the top of the call tree.
total is the function and everything it called. A function with a small self and a large total is a wrapper: the time is further down.
In the report above, parse_row accounts for 36.90 ms of the run, but only 15.88 ms of that is its own work - the other 21 ms is the 60,000 normalise calls it makes.
The report goes to stderr
So a profiled run still pipes. These two write the same file:
ecko app.ecko > out.txt
ecko profile app.ecko > out.txt
The program's exit code is its own, too. A program that fails still reports its numbers first, which is usually when you want them most.
Counted, not sampled
Every call is counted, so the call counts are exact and the same run gives the same ones every time. That costs a clock read entering and leaving each function, which a plain ecko app.ecko does not pay - profile a program when you want the numbers, run it normally the rest of the time.
Two things it does not break out:
- Builtins. Time inside
str.splitorjson.decodeis charged to the function that called it, not listed on its own. - The top level. Code outside any function is the "outside any function" figure on the summary line rather than a row.
AI calls
A run that made any ai calls gets a line for them:
0.91 ms total, 0.86 ms outside any function
2 ai calls
With a real provider it carries the token count and the estimated cost as well. In mock mode there is neither, because a mock call has no tokens and costs nothing - the call count is still real.
For per-call detail - prompts, responses, latency, retries - use ECKO_TRACE instead; profiling answers "where did the time go", tracing answers "what did it ask".