Benchmark Design

Warm-up, representative input, variance reporting, and guarding against dead-code elimination — what separates a trustworthy benchmark from a misleading number.

Purpose

A benchmark’s job is to measure real, steady-state performance — several common mistakes instead produce a number that looks precise but measures something else entirely.

Common mistakes and fixes

// Vulnerable: no warm-up, single run, unused result
function badBenchmark(fn) {
  const start = performance.now();
  fn(); // may be eliminated if the result is never used
  return performance.now() - start;
}

// Better: warm-up iterations, many measured iterations, result observed
function benchmark(fn, warmupRuns = 100, iterations = 1000) {
  for (let i = 0; i < warmupRuns; i++) fn();

  let sink = 0;
  const start = performance.now();
  for (let i = 0; i < iterations; i++) sink += fn();
  const elapsed = performance.now() - start;

  console.log(sink); // discourage the engine from eliminating the loop as dead code
  return elapsed / iterations;
}

Behavior notes

  • Warm-up runs let the engine reach steady-state optimized execution before the timed portion begins — a cold run measures JIT compilation overhead, not real performance.
  • Dead-code elimination: an engine that can prove a computed result is never observed may legally skip the work — using the result (accumulating it, logging it) defends against this.
  • Representative input: a benchmark on tiny, uniform, or otherwise unrealistic data can favor an approach that loses on real production data.
  • Variance: reporting a single number without a sense of spread across many runs risks mistaking noise for a real difference — running the whole benchmark multiple times and reporting a range (or a statistical summary) is more trustworthy than one number.

Common mistakes

  • Comparing two benchmarks run under different conditions (different warm-up, different iteration counts, different machine load) as if the numbers were directly comparable.
  • Treating a lab benchmark result as a final verdict without confirming it matters against field data — recall lab versus field data from Performance and Diagnostics.

Runtime notes

Applies to benchmarking JavaScript in any engine — the specific pitfalls (JIT warm-up, dead-code elimination) are consequences of how modern engines optimize, not unique to one runtime.

Taught in these lessons

Related reference

Updated 2026-09-03