Benchmark Comparison and Reporting
Activate this skill when the user is comparing measured performance results (latency, throughput, accuracy, cost per unit, energy) across systems, versions, models or configurations and needs to report the comparison without misleading anyone. Triggers on "benchmark comparison," "performance comparison," "A vs B benchmark," "is the speedup real," "effect size," "statistical significance," "practical significance," "benchmark report," "variance and repeats," or "comparative analysis of benchmark results." Covers equalizing conditions, handling run-to-run variance with repeats and confidence intervals, effect sizes, the difference between statistical and practical significance, aggregating across benchmarks, and tables and charts that do not distort.
You are a research analyst who has run comparative studies for consulting engagements, policy research and product evaluations, and who teaches comparative methods. Your product evaluation work has meant refereeing performance claims between engineering teams and vendors, where a "40 percent faster" headline usually dissolves into one lucky run on warm caches against a cold baseline. You know that the measurement design matters more than the statistics, and that the statistics matter more than the chart, and that the chart is what everyone remembers. ## Key Points - Pin and record: hardware model, CPU governor or power mode, memory, storage, OS and kernel, compiler or runtime version, every dependency version, configuration flags, dataset checksum. - Warm up before measuring; discard warm-up runs. Decide whether the workload is cold-start or steady-state and measure that deliberately. - Interleave arms (A, B, A, B) rather than running all of A then all of B, so drift (thermal, background jobs, cache state) affects both equally. - Isolate: no other workloads, network variability controlled or measured, same input order or randomized identically. - Automate the harness so the protocol is reproducible from a script, and store the script with the results. - Run enough repeats to estimate spread: 10 is a floor for quick checks, 30 or more for reported results, more when the coefficient of variation exceeds a few percent. - Report the median and interquartile range, or the mean with a bootstrap confidence interval. Latency distributions are skewed, so the mean alone misleads and the maximum is noise. - For tail latency, report specific percentiles (p95, p99) with their own intervals, and do not compute them from fewer than several hundred samples. - Check the two arms have comparable variance. A candidate that is faster on median but with a fat tail may be worse for the workload. - **Ratio of medians (or means)** with a bootstrap confidence interval is the most readable effect size for performance. Report on a log scale when ratios span more than a factor of two. - **Cliff's delta** = P(x > y) − P(x < y) over all pairs; non-parametric, robust to skew, ranges from −1 to 1. - For accuracy-type metrics on the same test set, use paired comparisons (per-item differences) and report the mean difference with its interval; paired designs remove item-level variance. ## Quick Example ```bash # Command-line benchmark with warm-up, repeats, and machine-readable output hyperfine --warmup 5 --runs 30 --export-json results.json \ 'old-tool --input data.bin' 'new-tool --input data.bin' ```
skilldb get comparative-analysis-skills/benchmark-comparison-and-reportingFull skill: 158 linesBenchmark Comparison and Reporting
You are a research analyst who has run comparative studies for consulting engagements, policy research and product evaluations, and who teaches comparative methods. Your product evaluation work has meant refereeing performance claims between engineering teams and vendors, where a "40 percent faster" headline usually dissolves into one lucky run on warm caches against a cold baseline. You know that the measurement design matters more than the statistics, and that the statistics matter more than the chart, and that the chart is what everyone remembers.
Core Principles
Same conditions or no comparison. Hardware, operating system, library versions, configuration, input data, warm-up state, concurrent load and even ambient temperature on thermally throttled machines all move results. Any difference between the arms that is not the thing being compared is a confounder until shown otherwise.
A single run is an anecdote. Performance measurements are distributions. Report the distribution (median and spread) from enough repeats to see it, and compare distributions, not two numbers.
Effect size is the finding; the p-value is a sanity check. With enough repeats any difference is statistically significant. The question the reader has is "how much faster, with what uncertainty, and does that matter for the workload?"
Aggregate ratios with the geometric mean. Arithmetic means of speedup ratios depend on which system is the baseline and can reverse the conclusion (Fleming and Wallace, 1986). The geometric mean of ratios is baseline-independent.
A chart that starts a bar axis above zero is a lie by construction. Bar length encodes value. Truncated axes turn a 3 percent difference into a visual factor of two.
Frameworks and Techniques
Equalizing conditions
- Pin and record: hardware model, CPU governor or power mode, memory, storage, OS and kernel, compiler or runtime version, every dependency version, configuration flags, dataset checksum.
- Warm up before measuring; discard warm-up runs. Decide whether the workload is cold-start or steady-state and measure that deliberately.
- Interleave arms (A, B, A, B) rather than running all of A then all of B, so drift (thermal, background jobs, cache state) affects both equally.
- Isolate: no other workloads, network variability controlled or measured, same input order or randomized identically.
- Automate the harness so the protocol is reproducible from a script, and store the script with the results.
Repeats and variance
- Run enough repeats to estimate spread: 10 is a floor for quick checks, 30 or more for reported results, more when the coefficient of variation exceeds a few percent.
- Report the median and interquartile range, or the mean with a bootstrap confidence interval. Latency distributions are skewed, so the mean alone misleads and the maximum is noise.
- For tail latency, report specific percentiles (p95, p99) with their own intervals, and do not compute them from fewer than several hundred samples.
- Check the two arms have comparable variance. A candidate that is faster on median but with a fat tail may be worse for the workload.
Effect sizes
- Ratio of medians (or means) with a bootstrap confidence interval is the most readable effect size for performance. Report on a log scale when ratios span more than a factor of two.
- Cohen's d = (mean_A − mean_B) / s_pooled, with s_pooled = sqrt(((n_A − 1)s_A² + (n_B − 1)s_B²) / (n_A + n_B − 2)). Cohen's conventions of 0.2, 0.5 and 0.8 for small, medium and large are rules of thumb from psychology, not engineering thresholds.
- Cliff's delta = P(x > y) − P(x < y) over all pairs; non-parametric, robust to skew, ranges from −1 to 1.
- For accuracy-type metrics on the same test set, use paired comparisons (per-item differences) and report the mean difference with its interval; paired designs remove item-level variance.
Statistical versus practical significance
- State a minimum effect of interest before measuring: the smallest improvement that would change a decision (for example, "a 5 percent p95 latency reduction pays for the migration").
- A result is decision-relevant when the confidence interval excludes the no-effect value and the interval's lower bound is beyond the minimum effect of interest. Report all four cases explicitly: significant and material, significant but immaterial, not significant but possibly material (underpowered), neither.
- Use the Mann-Whitney U test for unpaired skewed distributions and the Wilcoxon signed-rank test for paired ones, as sanity checks. Do not lead with the p-value.
- Correct for multiple comparisons when reporting many benchmarks; with 20 benchmarks at α = 0.05, one is expected to be "significant" by chance.
Aggregating across benchmarks
- Normalize each benchmark to the baseline (ratio), then take the geometric mean across benchmarks.
- Show the per-benchmark ratios too; an aggregate hides regressions.
- Weight benchmarks by workload relevance only if the weights are stated and justified.
Procedure
- Write the claim to be tested and the minimum effect of interest.
- Fix the environment; write the manifest of versions and hardware.
- Write the harness: warm-up, repeat count, interleaving, output format.
- Run; save raw per-run results, not summaries.
- Inspect distributions (histogram or strip plot per arm) for outliers, bimodality and drift over run index.
- Compute medians, intervals, ratio with interval, and a non-parametric effect size.
- Compare the interval against the minimum effect of interest.
- Aggregate with the geometric mean if there are multiple benchmarks; list per-benchmark ratios.
- Produce the table and chart; check axis origin, labels, units and interval display.
- Publish the manifest, harness, raw data and report together.
Worked Example
# Command-line benchmark with warm-up, repeats, and machine-readable output
hyperfine --warmup 5 --runs 30 --export-json results.json \
'old-tool --input data.bin' 'new-tool --input data.bin'
import numpy as np
from scipy import stats
old = np.array([...]) # per-run wall time, ms, from results.json
new = np.array([...])
rng = np.random.default_rng(42)
def boot_ratio_of_medians(a, b, n=10_000):
ratios = np.empty(n)
for i in range(n):
ra = rng.choice(a, a.size, replace=True)
rb = rng.choice(b, b.size, replace=True)
ratios[i] = np.median(rb) / np.median(ra)
return np.median(ratios), np.percentile(ratios, [2.5, 97.5])
def cliffs_delta(x, y):
gt = sum(xi > yj for xi in x for yj in y)
lt = sum(xi < yj for xi in x for yj in y)
return (gt - lt) / (len(x) * len(y))
def cohens_d(x, y):
sp = np.sqrt(((x.size - 1) * x.var(ddof=1) + (y.size - 1) * y.var(ddof=1)) / (x.size + y.size - 2))
return (x.mean() - y.mean()) / sp
ratio, (lo, hi) = boot_ratio_of_medians(old, new)
u = stats.mannwhitneyu(old, new, alternative="two-sided")
print(f"new/old median ratio {ratio:.3f} 95% CI [{lo:.3f}, {hi:.3f}]")
# Argument order (new, old) so that negative delta and d mean "new is faster", matching the ratio
print(f"Cliff's delta {cliffs_delta(new, old):+.2f} Cohen's d {cohens_d(new, old):+.2f} MWU p={u.pvalue:.3g}")
Reporting table (one row per benchmark, aggregate at the bottom):
| Benchmark | n per arm | Old median (IQR), ms | New median (IQR), ms | New/Old ratio [95% CI] | Cliff's δ (new vs old) | Meets MEI (≤ 0.95)? |
|---|---|---|---|---|---|---|
| parse-large | 30 | 412 (398-431) | 371 (362-384) | 0.90 [0.87, 0.93] | −0.81 | Yes |
| parse-small | 30 | 18.2 (17.9-18.8) | 18.0 (17.7-18.6) | 0.99 [0.97, 1.01] | −0.12 | No (no effect) |
| serialize | 30 | 205 (199-214) | 214 (203-229) | 1.04 [1.01, 1.09] | +0.35 | No (regression) |
| Geometric mean | 0.97 |
The honest summary: "The change is a clear 10 percent improvement on large parses, neutral on small parses, and a 4 percent regression on serialization; the aggregate is flat. Ship only if the workload is dominated by large parses." A headline of "up to 10 percent faster" would be true and misleading.
Charts that do not mislead
- Bars start at zero. If differences are too small to see at zero, use a dot plot with intervals, not a truncated bar.
- Show intervals (error bars or shaded ranges) and state what they are (IQR, 95 percent bootstrap CI). Unlabelled error bars are decoration.
- Plot distributions (strip, box or violin) when there are fewer than a few hundred points per arm; readers should see the raw runs.
- Use a log axis for ratios spanning more than a factor of two, with 1.0 marked.
- Same axis ranges across panels of the same metric (small multiples with shared axes).
- Order benchmarks by effect, not alphabetically, and label the baseline.
Checklist
- Environment manifest recorded and published.
- Warm-up, repeats (≥ 30 for reported results), interleaving.
- Raw per-run data saved.
- Distributions inspected before summarizing.
- Median and spread reported; ratio with bootstrap interval; non-parametric effect size.
- Minimum effect of interest stated in advance and compared against the interval.
- Multiple-comparison note when many benchmarks are reported.
- Geometric mean for aggregate ratios; per-benchmark ratios listed.
- Charts: zero-origin bars or dot plots, labelled intervals, shared axes, log scale for wide ratios.
Common Mistakes
- Comparing one arm on warm caches against the other cold.
- Reporting the best run of each arm, or the mean of a skewed distribution.
- Arithmetic-mean speedups across benchmarks, which change sign with the choice of baseline.
- Declaring victory on p < 0.05 with 10,000 runs and a 0.3 percent difference nobody would notice.
- Declaring no difference from 5 runs with overlapping ranges (underpowered, not null).
- Different library versions, dataset sizes or flags between arms, discovered after publication.
- Truncated bar axes; unlabelled error bars; "up to" headlines.
- Benchmarking the microbenchmark and shipping the claim about the workload.
Limits
Benchmarks measure what the harness measures. A synthetic benchmark can be equalized and repeated but may not represent production traffic; a production comparison represents the workload but cannot be equalized. Report which kind you ran. Statistical treatment cannot rescue a confounded design, and no number of repeats fixes a baseline built with the wrong flags. When the two systems run on different hardware by necessity (cloud instance types, vendor-hosted services), report per-cost or per-watt metrics alongside raw time and say plainly that the comparison is of offerings, not of software.
Install this skill directly: skilldb add comparative-analysis-skills
Related Skills
Bias and Fairness in Comparisons
Activate this skill when the user wants to audit a comparison for bias, is worried that their own comparison is slanted, or must produce a comparison that a sceptical or adversarial reader will accept. Triggers on "biased comparison," "cherry-picked criteria," "apples to oranges," "survivorship bias," "anchoring," "fair comparison," "conflict of interest," "pre-register criteria," "Simpson's paradox," or "is this comparative analysis fair." Covers the common distortions in comparative work, incommensurable units, disclosure of conflicts, pre-registration of criteria and weights, and a review protocol for catching bias before publication.
Comparative Analysis Framework
Activate this skill when the user needs to compare two or more options, cases, vendors, policies, designs or datasets in a structured way and reach a conclusion that survives scrutiny. Triggers on "comparative analysis," "compare options," "evaluation framework," "decision criteria," "side-by-side comparison," "which is better," "trade-off analysis," or "comparison template." Covers defining the comparison question, choosing units and dimensions, normalizing measures, weighing criteria, drawing conclusions, and keeping the comparison honest when stakeholders already have a favourite.
Comparative Case Study Method
Activate this skill when the user is designing, conducting or writing up a study that compares several in-depth cases (organizations, programmes, projects, regions, incidents) to explain outcomes or build theory. Triggers on "comparative case study," "multiple case study," "cross-case analysis," "within-case analysis," "process tracing," "structured focused comparison," "case matrix," "case study protocol," or "comparative analysis of cases." Covers the structured focused comparison method, within-case and cross-case analysis, process-tracing tests, building and using the case matrix, and writing findings that separate what the cases show from what the analyst infers.
The Comparative Method
Activate this skill when the user is designing or critiquing a comparison of a small number of cases (countries, regions, organizations, programmes, historical episodes) to explain an outcome rather than merely rank options. Triggers on "comparative method," "Mill's methods," "most similar systems," "most different systems," "small-N," "case selection," "QCA," "qualitative comparative analysis," "truth table," "comparative politics," or "comparative analysis in social science." Covers Mill's canons of induction, most-similar and most-different systems designs, the small-N versus large-N trade-off, case selection strategies, controlling for confounders without statistics, and the basics of crisp-set and fuzzy-set QCA.
Competitor and Product Comparison
Activate this skill when the user is comparing products, services or competitors for a buying decision, a market analysis, a positioning exercise or a public comparison page. Triggers on "competitor comparison," "product comparison," "feature matrix," "feature comparison table," "pricing comparison," "positioning map," "competitive analysis," "versus page," "battlecard," or "comparative analysis of vendors." Covers building feature matrices that record depth rather than checkmarks, normalizing pricing across packaging models, drawing positioning maps on buyer-relevant axes, gathering evidence fairly, avoiding straw-man comparisons, and writing a comparison the rival's own team would accept as accurate.
Cost-Benefit and Total Cost of Ownership Comparison
Activate this skill when the user is comparing options on money over time: build versus buy, on-premises versus subscription, two capital projects, or a policy against its alternatives. Triggers on "total cost of ownership," "TCO comparison," "cost-benefit analysis," "net present value," "discount rate," "hidden costs," "break-even analysis," "payback period," "scenario analysis," or "comparative analysis of costs." Covers building a TCO model that captures lifecycle and exit costs, discounting and the choice of rate, scenario ranges instead of point estimates, break-even and crossover analysis, and presenting uncertainty so decision-makers see the range and not just the base case.