0Pricing
Lua Academy · Lesson

Benchmarking Patterns

Write reliable micro-benchmarks using os.clock and avoid common pitfalls.

Benchmarking Patterns is a free Lua Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Benchmark?

Micro-benchmarks measure the performance of a specific code snippet in isolation. They help verify that an optimization actually improves speed without relying on intuition.

Basic Benchmark Template

Wrap the code in a loop, measure wall time with os.clock(), and divide by iteration count.

local N = 1e6
local t0 = os.clock()
for i = 1, N do
  -- code to benchmark
end
local elapsed = os.clock() - t0
print(("%.2f ns/op"):format(elapsed / N * 1e9))

Warm-Up Pass

Run a warm-up pass before timing to let LuaJIT compile traces. Without warm-up, the first timed run includes JIT compilation overhead.

for i = 1, 1000 do hotFunction(i) end  -- warm up
local t0 = os.clock()
for i = 1, N do hotFunction(i) end
local elapsed = os.clock() - t0

Preventing Dead-Code Elimination

The JIT may optimize away computations whose results are unused. Accumulate results into a variable to keep the benchmark honest.

local sum = 0
for i = 1, N do sum = sum + math.sin(i) end
print(sum)  -- prevent elimination

Comparing Two Approaches

Benchmark alternative implementations under identical conditions. Run them interleaved or multiple times to minimize OS scheduling noise.

local function approach1() -- ...
end
local function approach2() -- ...
end
local function bench(fn, n)
  local t = os.clock()
  for _ = 1, n do fn() end
  return os.clock() - t
end
print("A:", bench(approach1, 1e5))
print("B:", bench(approach2, 1e5))

Statistical Analysis

Run the benchmark multiple times and compute min, max, and median. Outliers from GC pauses or OS scheduling should be discarded.

Memory Benchmarking

Measure memory allocation alongside timing.

collectgarbage("collect")
local mem0 = collectgarbage("count")
-- ... run operation ...
collectgarbage("collect")
local mem1 = collectgarbage("count")
print(("Memory delta: %.1f KB"):format(mem1 - mem0))

Avoiding GC Interference

Stop the GC before timing to measure pure computation time. Resume it after.

collectgarbage("stop")
local t0 = os.clock()
for i = 1, N do -- ... end
print(os.clock() - t0)
collectgarbage("restart")

Realistic vs Micro Benchmarks

Micro-benchmarks optimize small snippets but may not reflect real-world performance. Always validate improvements against a full application profile.

Benchmark Utilities

Build a reusable benchmark(name, fn, iters) utility that prints consistent, formatted results across all your benchmarks.

local function benchmark(name, fn, iters)
  iters = iters or 1e5
  for _ = 1, iters // 10 do fn() end  -- warm up
  local t = os.clock()
  for _ = 1, iters do fn() end
  local ns = (os.clock() - t) / iters * 1e9
  print(("%-30s %8.1f ns/op"):format(name, ns))
end

CI Benchmarking

Run benchmarks in CI to detect performance regressions. Alert if a benchmark degrades by more than a defined threshold (e.g., 10%).

Benchmark Question

Why is a warm-up pass important when benchmarking LuaJIT code?

Recap: Benchmarking Patterns

Use a warm-up pass, prevent dead-code elimination by using results, measure with os.clock(), control GC, and run multiple trials for stable measurements. Build a reusable benchmark utility for consistency.

Frequently asked questions

Is the “Benchmarking Patterns” lesson free?

Yes — the full text of “Benchmarking Patterns” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.

What will I learn in “Benchmarking Patterns”?

Write reliable micro-benchmarks using os.clock and avoid common pitfalls. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Benchmarking Patterns” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. LuaJIT Architecture Overview
  2. Writing JIT-Friendly Lua
  3. Profiling with jit.p and perf
  4. Benchmarking Patterns
← Back to Lua Academy