How do I identify hot methods in EK9 profiling output?

← Profiling · Ref: Q630

The profiler output includes a hot function table that lists functions sorted by self-time. The top entries are your optimisation targets.

HOT FUNCTION TABLE

The -t6p HTML dashboard and -tp human-readable output both include a table with columns:
- Function name: fully qualified (module::type.method or module::function).
- Call count: how many times the function was invoked.
- Self time: time spent in this function only.
- Total time: time including all functions it calls.
- Avg time: average time per call.
- p95: 95th percentile call time.
- p99: 99th percentile call time.

SORTING STRATEGY

Sort by self-time to find functions doing the most work. Sort by call count to find functions called excessively. Sort by p99 to find functions with occasional slow calls (latency spikes).

THREE OPTIMISATION PATTERNS

1. High self-time, low call count: the function itself is slow. Optimise its algorithm.
2. Low self-time, very high call count: the function is fast but called too often. Reduce call frequency (cache results, batch operations).
3. High p99 with low average: occasional slow path. Check for conditional branches that hit slow code paths intermittently.

JSON FOR AUTOMATED ANALYSIS

  ek9 -t2p myproject.ek9

The JSON output can be consumed by AI assistants or CI scripts to:
- Flag functions where p99 exceeds a threshold.
- Track self-time trends across builds.
- Identify call count regressions.

See Q627 for profiling programs. See Q629 for reading flame graphs. See Q631 for benchmarking two approaches. See Q312 for complexity metrics. See Q322 for profiling overview.

Example

defines module qa.profilingdeep.hotmethods

  defines function

    <?-
      Three functions with different profiling characteristics:
      - expensiveComputation: high self-time (does real work).
      - cheapHelper: low self-time, high call count.
      - orchestrator: high total time, low self-time.
    -?>
    expensiveComputation() as pure
      -> iterations as Integer
      <- accumulator as Float: 0.0

      for i in 1 ... iterations
        term <- 1.0 / Float(i)
        accumulator: accumulator + term

    cheapHelper() as pure
      -> number as Float
      <- doubled as Float: number * 2.0

    orchestrator()
      -> limit as Integer
      <- result as Float: 0.0

      thousand <- 1000
      raw <- expensiveComputation(thousand)
      for i in 1 ... limit
        result: cheapHelper(raw)

  defines program

    HotMethodsDemo()
      stdout <- Stdout()

      repetitions <- 50
      finalValue <- orchestrator(repetitions)
      stdout.println(`Result: ${finalValue}`)

Common mistakes

E11051 — Calling a pure function without capturing its return value is dead code. Pure functions have no side effects. See ek9 -h E11051 for details.

Incorrect:

cheapHelper(raw)

Correct:

result: cheapHelper(raw)
Other ways to ask this
  • How do I find the slowest functions in my EK9 program?
  • What is the hot function table in EK9 profiling?
  • How do I know which function to optimise first?

Coming from another language?

Java: JFR hot methods view in JMC, async-profiler flat profile. Python: cProfile cumulative/tottime columns, py-spy top view. Rust: perf report sorted by overhead. Go: go tool pprof top command. JavaScript: Chrome DevTools Bottom-Up view. EK9: built-in hot function table in -tp (text) and -t6p (HTML), sorted by self-time, with p95/p99 percentiles, JSON export for CI.

Keywords: function, count, p95, table, flame-graph, profile, sort, optimise, slow, hot, self-time, method, call, performance, p99