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.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
107
tests/bench/BeforeAfterBenchmark.java
Normal file
107
tests/bench/BeforeAfterBenchmark.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue