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
#!ek9 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: benchmark, date, duration, elapsed, measure, millisecond, performance, profile, systemclock, time, timezone, timing