Back to WCA Statistics

Dominance

World record

Dominance measures how far the top seat is from the rest. Concretely: across an event's full history, how many of the current #1's individual results are strictly faster than every other person's best? That count is dominance.

P claims #1 through #N alone with all of their own marks = high-score domination; P beats #2 by 0.01s = near-zero dominance even though they hold the WR. Two metrics (single / average) × two views (live ranking / WR evolution), with the history view drawing how that depth grew.

By the numbers

count
Primary metric
Count of P's results strictly < others' best
2 + 2
Panels
Single/Average × Ranking/History
~5 M
Rows scanned (333)
Per-event scan of result_attempts
O(log n)
Update cost
Per-person sorted array + binary insert

Data source

Single mode reads result_attempts (one row per solve), Average mode reads results.average (one row per round). Both scan per-event in start_date order, without embedded person/comp link strings (slim rows save ~2GB at 5M rows).

During the scan, maintain a sorted array + running best per person; at each date boundary check whether dominance just hit a new max. Final markdown links are resolved with one IN (...) query over the surviving few dozen IDs.

sql
-- Single (瘦行)
SELECT result.person_id, ra.value,
       result.competition_id AS comp_id, competition.start_date
FROM result_attempts ra
JOIN results result ON result.id = ra.result_id
JOIN competitions competition ON competition.id = result.competition_id
WHERE ra.value > 0 AND result.event_id = '<event>'
ORDER BY competition.start_date;

Algorithm / pipeline

1
Per-event load slim rows, sorted by date
Single ← result_attempts.value; Average ← results.average. Just four columns: person_id / value / comp_id / start_date — markdown links are resolved later, dodging string bloat across millions of rows.
2
Per-person sorted array + best
Stream through, binary-insert each value (bisectLeft) into pv[person] (sorted array of all valid times for that person). Maintain pb[person] = running best.
3
On date boundary: compute dominance
When start_date rolls forward, scan pb: find global leader P + the second-best across everyone else (others_best). Then bisectLeft(pv[P], others_best) = number of P's results strictly faster than others_best. That's the day's dominance count.
4
History: keep strict refreshes only
On boundary, if count > maxDom strictly, log a WR event: current P, comp, date, plus the comp where that person first reached domination (firstDom). Later compute improvement = +(count - prev.count) and run-length days.
5
Resolve markdown links in one IN(...) pass
After all events finish, batch-resolve every accumulated person_id / comp_id with one IN (...) query against persons / competitions to build markdown links; substitute slim-row IDs with link strings; emit 4 panels (2 metrics × {ranking, history}).

Key formulae

Dominance count
dom(P, t) = | { v ∈ results(P, ≤t) : v < min_{Q ≠ P} best(Q, ≤t) } |
t = current point in time. The count of P's results (up to t) that are strictly faster than the best result of any other person (up to t).

Caveats & edges

Related stats & links