110 lines
3.8 KiB
Java
110 lines
3.8 KiB
Java
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");
|
||
}
|
||
}
|