From 3b4f765e03c4b0ed5e44750eab575012ad88f3e6 Mon Sep 17 00:00:00 2001 From: Stephen Waits Date: Thu, 14 May 2026 06:41:33 -0600 Subject: [PATCH] perf(operators): make PMX and OX crossovers O(n) with value-indexed lookups Both crossovers had an O(n) inner scan making them O(n^2): PMX located the value to swap with `child.iter().position`, OX tested segment membership with `segment.contains`. Both operate on strict permutations of 0..n, so a value-indexed table (PMX: position kept in sync across swaps; OX: a static membership bitmap) gives O(1) lookups. debug_asserts document the range assumption, consistent with ERX and CX. pmx_crossover_vary n=100: 21_507 -> 5_900 (-73%, 3.65x); n=30 -18%. order_crossover_vary n=100: 18_265 -> 7_389 (-60%, 2.47x); n=30 -29%. All four permutation crossovers are now O(n). Bit-identical for valid permutations -- all 606 tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/operators/permutation.rs | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/operators/permutation.rs b/src/operators/permutation.rs index 31eb652..9a261d1 100644 --- a/src/operators/permutation.rs +++ b/src/operators/permutation.rs @@ -372,12 +372,20 @@ fn ox_child(donor: &[usize], filler: &[usize], lo: usize, hi: usize) -> Vec Vec