perf(pareto): skip already-dominated points in pareto_front

`pareto_front` re-scanned every candidate from scratch. Track a
`dominated` bitset instead: whenever `i`'s scan finds `i` dominates `j`,
mark `j` so the outer loop skips `j` outright when it reaches it. The
inner check now reads both directions of `pareto_compare` — the
objective scan already computes both flags, so this is ~free.

Bit-identical, including under NaN-intransitive dominance: a mark is
only ever set from a direct pairwise `pareto_compare` result, never
inferred transitively. Also strict-or-neutral on work — the marks can
only ever let the outer loop *skip*, never add a scan.

Whole-program callgrind Ir for the compare_profile benchmark:
169,440,644,233 -> 165,311,562,939 (-2.44%); `pareto_front` self-Ir
44.1B -> 39.9B.
This commit is contained in:
2026-05-14 12:49:47 -06:00
parent 66b4d9fa6b
commit a4b11f286e
+26 -9
View File
@@ -55,8 +55,19 @@ pub fn pareto_front<D: Clone>(
oriented.extend_from_slice(&objectives.as_minimization(&c.evaluation.objectives)); oriented.extend_from_slice(&objectives.as_minimization(&c.evaluation.objectives));
} }
// `dominated[j]` is set the moment some candidate is found to dominate
// `j`. Whenever `i`'s scan finds `i` dominates `j`, mark `j` so the
// outer loop can skip `j` entirely when it reaches it. This never does
// more work than the plain scan — the marks only ever let us *skip* —
// and it stays bit-identical even under NaN-intransitive dominance:
// a mark is set only from a direct pairwise `pareto_compare` result,
// never inferred transitively.
let mut dominated: Vec<bool> = vec![false; n];
let mut out = Vec::new(); let mut out = Vec::new();
'outer: for i in 0..n { 'outer: for i in 0..n {
if dominated[i] {
continue 'outer;
}
let ai_feasible = feasible[i]; let ai_feasible = feasible[i];
let ai_violation = violation[i]; let ai_violation = violation[i];
let ai = &oriented[i * m..i * m + m]; let ai = &oriented[i * m..i * m + m];
@@ -64,13 +75,13 @@ pub fn pareto_front<D: Clone>(
if i == j { if i == j {
continue; continue;
} }
// `i` is kept only if no `j` dominates it — i.e. no `j` for which // Inline both directions of `pareto_compare`: `j` dominating
// `pareto_compare(a_i, a_j)` would be `DominatedBy`. This inlines // `i` excludes `i`; `i` dominating `j` lets us skip `j`'s own
// exactly that one outcome of `pareto_compare`. // scan later.
let dominated_by_j = match (ai_feasible, feasible[j]) { let (i_dominates_j, j_dominates_i) = match (ai_feasible, feasible[j]) {
(true, false) => false, (true, false) => (true, false),
(false, true) => true, (false, true) => (false, true),
(false, false) => ai_violation > violation[j], (false, false) => (ai_violation < violation[j], ai_violation > violation[j]),
(true, true) => { (true, true) => {
let aj = &oriented[j * m..j * m + m]; let aj = &oriented[j * m..j * m + m];
let mut a_better_anywhere = false; let mut a_better_anywhere = false;
@@ -84,12 +95,18 @@ pub fn pareto_front<D: Clone>(
b_better_anywhere = true; b_better_anywhere = true;
} }
} }
b_better_anywhere && !a_better_anywhere (
a_better_anywhere && !b_better_anywhere,
b_better_anywhere && !a_better_anywhere,
)
} }
}; };
if dominated_by_j { if j_dominates_i {
continue 'outer; continue 'outer;
} }
if i_dominates_j {
dominated[j] = true;
}
} }
out.push(population[i].clone()); out.push(population[i].clone());
} }