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));
}
// `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();
'outer: for i in 0..n {
if dominated[i] {
continue 'outer;
}
let ai_feasible = feasible[i];
let ai_violation = violation[i];
let ai = &oriented[i * m..i * m + m];
@@ -64,13 +75,13 @@ pub fn pareto_front<D: Clone>(
if i == j {
continue;
}
// `i` is kept only if no `j` dominates it — i.e. no `j` for which
// `pareto_compare(a_i, a_j)` would be `DominatedBy`. This inlines
// exactly that one outcome of `pareto_compare`.
let dominated_by_j = match (ai_feasible, feasible[j]) {
(true, false) => false,
(false, true) => true,
(false, false) => ai_violation > violation[j],
// Inline both directions of `pareto_compare`: `j` dominating
// `i` excludes `i`; `i` dominating `j` lets us skip `j`'s own
// scan later.
let (i_dominates_j, j_dominates_i) = match (ai_feasible, feasible[j]) {
(true, false) => (true, false),
(false, true) => (false, true),
(false, false) => (ai_violation < violation[j], ai_violation > violation[j]),
(true, true) => {
let aj = &oriented[j * m..j * m + m];
let mut a_better_anywhere = false;
@@ -84,12 +95,18 @@ pub fn pareto_front<D: Clone>(
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;
}
if i_dominates_j {
dominated[j] = true;
}
}
out.push(population[i].clone());
}