v8-0004 + jsc-0003: Maglev KnownMapsMerger O(P×R) std::find, IntegerRangeOpt liveAtHead O(50×B×R×L); 2+2 PASS; count 606→608

This commit is contained in:
russell@unturf.com 2026-03-27 23:00:07 -04:00
parent ae91f05bf3
commit 87099aaaac
9 changed files with 328 additions and 8 deletions

View file

@ -0,0 +1,110 @@
package unit;
import java.util.*;
/**
* jsc-0003: DFGIntegerRangeOptimizationPhase liveAtHead
* Vector::contains O(50×B×R×L) → HashSet O(50×B×R)
*
* SLOW: simulates WTF::Vector<NodeFlowProjection>.contains() — O(L) per check
* FAST: simulates UncheckedKeyHashSet::contains() — O(1) per check
*/
public class JSCIntegerRangeLiveAtHeadTest {
static long cmpOps = 0;
// SLOW: O(L) linear scan per contains check (Vector::contains)
static boolean vectorContains(List<Integer> liveAtHead, int node) {
for (int live : liveAtHead) {
cmpOps++;
if (live == node) return true;
}
return false;
}
// SLOW: full fixed-point pass O(50×B×R×L)
static int fixedPointSlow(List<List<Integer>> blocks,
List<List<Integer>> relationships,
List<List<Integer>> liveAtHeads) {
int count = 0;
for (int iter = 0; iter < 50; iter++) {
for (int b = 0; b < blocks.size(); b++) {
List<Integer> liveAtHead = liveAtHeads.get(b);
for (int node : relationships.get(b)) {
if (vectorContains(liveAtHead, node))
count++;
}
}
}
return count;
}
// FAST: pre-build HashSet per block — O(50×B×R)
static int fixedPointFast(List<List<Integer>> blocks,
List<List<Integer>> relationships,
List<List<Integer>> liveAtHeads) {
// Pre-build sets (done once per block in real impl)
List<Set<Integer>> liveSets = new ArrayList<>();
for (List<Integer> live : liveAtHeads)
liveSets.add(new HashSet<>(live));
int count = 0;
for (int iter = 0; iter < 50; iter++) {
for (int b = 0; b < blocks.size(); b++) {
Set<Integer> liveSet = liveSets.get(b);
for (int node : relationships.get(b)) {
if (liveSet.contains(node))
count++;
}
}
}
return count;
}
public static void main(String[] args) {
// B=20 blocks, R=30 relationships each, L=40 live nodes
int B = 20, R = 30, L = 40;
Random rng = new Random(42);
List<List<Integer>> blocks = new ArrayList<>();
List<List<Integer>> relationships = new ArrayList<>();
List<List<Integer>> liveAtHeads = new ArrayList<>();
for (int b = 0; b < B; b++) {
blocks.add(Collections.emptyList());
List<Integer> rels = new ArrayList<>();
for (int r = 0; r < R; r++) rels.add(rng.nextInt(60));
relationships.add(rels);
List<Integer> live = new ArrayList<>();
for (int l = 0; l < L; l++) live.add(l);
liveAtHeads.add(live);
}
// Verify correctness
int slowCount = fixedPointSlow(blocks, relationships, liveAtHeads);
int fastCount = fixedPointFast(blocks, relationships, liveAtHeads);
if (slowCount != fastCount) {
System.err.printf("FAIL: slow=%d fast=%d%n", slowCount, fastCount);
System.exit(1);
}
// Measure SLOW ops
cmpOps = 0;
fixedPointSlow(blocks, relationships, liveAtHeads);
long slowCmp = cmpOps;
// FAST ops: 50 × B × R hash lookups (O(1) each)
long fastOps = 50L * B * R;
double ratio = (double) slowCmp / Math.max(fastOps, 1);
System.out.printf("jsc-0003 IntegerRangeOptLiveAtHead: SLOW=%d cmpOps, FAST~=%d ops, ratio=%.1fx%n",
slowCmp, fastOps, ratio);
if (ratio < 5.0) {
System.err.println("FAIL: speedup ratio " + ratio + " < 5x");
System.exit(1);
}
System.out.println("PASS");
}
}