How do I measure elapsed time for benchmarking in EK9?
← Date, Time, and Duration · Ref: Q544
Use SystemClock().millisecond() before and after the code section, then subtract to get elapsed Millisecond.
BASIC TIMING PATTERN
startMs <- SystemClock().millisecond() // ... code to measure ... endMs <- SystemClock().millisecond() elapsed <- endMs - startMs stdout.println(`Elapsed: ${elapsed}`)
The result is a typed Millisecond value, not a raw integer. You can convert it to Duration with .duration() or get the raw value.
BUILT-IN PROFILING FLAGS
EK9 also has built-in profiling of the code your tests exercise: append 'p' to a test flag.
ek9 -tp program.ek9 tests, coverage, then the top functions by self-time ek9 -t2p program.ek9 writes the full profiling JSON to .ek9/coverage.json
(-P is packaging, not profiling.) The compiler instruments the code automatically. For micro-benchmarks, manual SystemClock timing gives you control over exactly what is measured.
MILLISECOND ARITHMETIC
You can accumulate timing results:
totalMs <- 0ms totalMs += elapsed
Or compute averages:
averageMs <- totalMs / iterations
CONVERT TO DURATION
asDuration <- elapsed.duration() // a Duration, for display in hours/minutes/seconds format
See Q41 for Millisecond type details. See Q543 for Unix timestamps. See Q322 for the profiling system. See Q631 for benchmarking two approaches.
Example
defines module qa.elapsed.time.benchmarking defines program ElapsedTimeBenchmarkingDemo() stdout <- Stdout() // Basic timing pattern startMs <- SystemClock().millisecond() // Simulate work with a loop counter <- 0 for i in 1 ... 1000 counter += i endMs <- SystemClock().millisecond() elapsed <- endMs - startMs stdout.println(`Loop elapsed: ${elapsed}`) stdout.println(`Counter: ${counter}`) // Convert to Duration asDuration <- elapsed.duration() stdout.println(`As Duration: ${asDuration}`) // Accumulate multiple measurements totalMs <- 0ms for run in 1 ... 3 runStart <- SystemClock().millisecond() sum <- 0 for j in 1 ... 500 sum += j runEnd <- SystemClock().millisecond() runElapsed <- runEnd - runStart totalMs += runElapsed stdout.println(`Run ${run}: ${runElapsed}`) stdout.println(`Total: ${totalMs}`) // Millisecond comparison for thresholds threshold <- 1000ms if totalMs < threshold stdout.println("Fast enough") else stdout.println("Too slow")
Common mistakes
E50001 — A name in the subtraction that was never declared (here a mistyped startMs) is not resolved, triggering E50001. See ek9 -h E50001 for details.
Incorrect:
elapsed <- endMs - startMsTypo
Correct:
elapsed <- endMs - startMs
E50001 — EK9 uses SystemClock().millisecond(), not static Java-style methods. SystemClock is instantiated then millisecond() is called on it. Triggers E50001 — method not resolved. See ek9 -h SystemClock for the full API.
Incorrect:
startMs <- SystemClock.currentTimeMillis()
Correct:
startMs <- SystemClock().millisecond()
Other ways to ask this
- How do I time how long something takes in EK9?
- How do I use SystemClock for performance measurement?
- How do I profile code execution time in EK9?
Coming from another language?
Java: System.nanoTime() for benchmarking (not currentTimeMillis which has clock adjustment issues). Python: time.perf_counter() or timeit module. JavaScript: performance.now() for high-resolution timing. Go: time.Now() with time.Since(). Rust: std::time::Instant::now() with elapsed(). EK9: SystemClock().millisecond() with typed subtraction, built-in profiling by appending 'p' to a test flag (-tp, -t2p).
Keywords: timezone, timing, elapsed, time, date, systemclock, performance, profile, benchmark, duration, measure, millisecond