whitepaper: re-add 10 missing entries + 11 new defects this session, count 578→590; rebuild PDF

This commit is contained in:
russell@unturf.com 2026-03-27 22:18:31 -04:00
parent e4ee168b1e
commit 2e4f7807d5
401 changed files with 3914 additions and 114 deletions

View file

@ -0,0 +1,90 @@
package unit;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* pulsar-0005 — PartialRoundRobinMessageRouterImpl CopyOnWriteArrayList.contains O(N×L) → HashSet O(N)
*
* The hot path in getOrCreatePartialList() is the filter lambda:
* .filter(e -> !partialList.contains(e))
*
* This benchmark isolates the membership test — N calls to contains()
* over a CopyOnWriteArrayList of size L vs a HashSet snapshot.
*
* SLOW: CopyOnWriteArrayList.contains(e) → O(L) per call → O(N × L) total
* FAST: HashSet.contains(e) → O(1) per call → O(N) total
*/
public class PulsarPartialRoundRobinRouterTest {
static long benchSlow(int N, int L) {
CopyOnWriteArrayList<Integer> partialList = new CopyOnWriteArrayList<>();
for (int i = 0; i < L; i++) {
partialList.add(i * 2); // even indices present
}
long start = System.nanoTime();
int found = 0;
for (int i = 0; i < N; i++) {
if (!partialList.contains(i)) found++; // O(L) per call
}
return System.nanoTime() - start;
}
static long benchFast(int N, int L) {
CopyOnWriteArrayList<Integer> partialList = new CopyOnWriteArrayList<>();
for (int i = 0; i < L; i++) {
partialList.add(i * 2);
}
// FIX: snapshot to HashSet before the filter loop
Set<Integer> existing = new HashSet<>(partialList);
long start = System.nanoTime();
int found = 0;
for (int i = 0; i < N; i++) {
if (!existing.contains(i)) found++; // O(1) per call
}
return System.nanoTime() - start;
}
public static void main(String[] args) {
int passed = 0;
int failed = 0;
int minRatio = 5;
// [N = numPartitions, L = partialList.size() at expand time]
int[][] cases = {
{500, 250},
{2000, 1000},
{5000, 2500},
};
// warmup
for (int w = 0; w < 3; w++) {
benchSlow(200, 100);
benchFast(200, 100);
}
for (int[] c : cases) {
int N = c[0];
int L = c[1];
long slowTotal = 0, fastTotal = 0;
int reps = 10;
for (int r = 0; r < reps; r++) {
slowTotal += benchSlow(N, L);
fastTotal += benchFast(N, L);
}
long slowAvg = slowTotal / reps;
long fastAvg = fastTotal / reps;
double ratio = fastAvg > 0 ? (double) slowAvg / fastAvg : 999.0;
boolean ok = ratio >= minRatio;
System.out.printf(" N=%-5d L=%-5d slow=%8dns fast=%7dns ratio=%.1fx %s%n",
N, L, slowAvg, fastAvg, ratio, ok ? "PASS" : "FAIL");
if (ok) passed++; else failed++;
}
System.out.printf("%nTotal: %d/%d PASS%n", passed, passed + failed);
if (failed > 0) System.exit(1);
}
}