java-topology/tests/bench/BeforeAfterBenchmark.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

107 lines
4.1 KiB
Java

package bench;
import support.TarjanAlgorithm;
import support.TarjanAlgorithm.Node;
import support.TarjanAlgorithm.Result;
import java.util.List;
/**
* Before/after timing benchmark for the Tarjan O(V²) defect.
*
* Uses the two self-contained implementations in TarjanAlgorithm:
* BEFORE (defective): stack.contains(n) — O(V²) per graph
* AFTER (fixed): n.onStack — O(V+E) per graph
*
* Graph topology: starWithBackEdges(V)
* N0 → N1..N(v-1), N_k → N0 for k=1..v-1
* Produces exactly V*(V+1)/2-1 comparisons (defective) vs V-1 (fixed).
*
* Output: side-by-side timing table + speedup ratio.
*
* Compile and run:
* cd tests
* java -m jdk.compiler/com.sun.tools.javac.Main -cp . \
* support/TarjanAlgorithm.java bench/BeforeAfterBenchmark.java
* java -cp . bench.BeforeAfterBenchmark
*/
public class BeforeAfterBenchmark {
static final int WARMUP = 2_000;
static final int TRIALS = 10_000;
public static void main(String[] args) {
System.out.println("=== Tarjan Before/After Timing Benchmark ===");
System.out.println("Graph: starWithBackEdges(V)");
System.out.println("Warmup: " + WARMUP + " iterations per size");
System.out.println("Trials: " + TRIALS + " iterations per size");
System.out.println();
printHeader();
int[] sizes = {10, 25, 50, 100, 200, 400, 800};
for (int v : sizes) {
runSize(v);
}
System.out.println();
System.out.println("Comparison counts (exact, not timing):");
printComparisonTable();
}
static void printHeader() {
System.out.printf("%-6s %-14s %-14s %-10s %-12s %-12s%n",
"V", "BEFORE ns/op", "AFTER ns/op", "speedup",
"BEFORE cmps", "AFTER cmps");
System.out.println("-".repeat(75));
}
static void runSize(int v) {
// ── warmup ───────────────────────────────────────────────────────────
for (int i = 0; i < WARMUP; i++) {
TarjanAlgorithm.tarjanDefective(TarjanAlgorithm.starWithBackEdges(v));
TarjanAlgorithm.tarjanFixed(TarjanAlgorithm.starWithBackEdges(v));
}
// ── timed: BEFORE ────────────────────────────────────────────────────
long beforeNs = 0;
for (int i = 0; i < TRIALS; i++) {
List<Node> g = TarjanAlgorithm.starWithBackEdges(v);
long t = System.nanoTime();
TarjanAlgorithm.tarjanDefective(g);
beforeNs += System.nanoTime() - t;
}
// ── timed: AFTER ─────────────────────────────────────────────────────
long afterNs = 0;
for (int i = 0; i < TRIALS; i++) {
List<Node> g = TarjanAlgorithm.starWithBackEdges(v);
long t = System.nanoTime();
TarjanAlgorithm.tarjanFixed(g);
afterNs += System.nanoTime() - t;
}
long beforePerOp = beforeNs / TRIALS;
long afterPerOp = afterNs / TRIALS;
double speedup = (double) beforePerOp / afterPerOp;
long beforeCmps = (long) v * (v + 1) / 2 - 1;
long afterCmps = v - 1;
System.out.printf("%-6d %-14d %-14d %-10.2fx %-12d %-12d%n",
v, beforePerOp, afterPerOp, speedup, beforeCmps, afterCmps);
}
static void printComparisonTable() {
System.out.printf("%-6s %-14s %-14s %-10s%n",
"V", "BEFORE cmps", "AFTER cmps", "ratio");
System.out.println("-".repeat(50));
int[] sizes = {10, 25, 50, 100, 200, 400, 800};
for (int v : sizes) {
long before = (long) v * (v + 1) / 2 - 1;
long after = v - 1;
System.out.printf("%-6d %-14d %-14d %.1fx%n",
v, before, after, (double) before / after);
}
}
}