package bench; import support.PostgresqlVarDedupAlgorithm; import support.PostgresqlVarDedupAlgorithm.Var; import support.PostgresqlExprMembershipAlgorithm; import support.PostgresqlExprMembershipAlgorithm.Expr; import support.PostgresqlExprMembershipAlgorithm.EquivalenceMember; import support.PostgresqlJoinMergeAlgorithm; import support.PostgresqlJoinMergeAlgorithm.RelTarget; import java.util.*; /** * PostgresqlBenchmark — timing benchmark for postgresql-0002, -0003, -0004. * * Three sites, all CWE-407 (missing visited/seen set), all fixable without * nodeHash() when the expressions involved are pure Var nodes. * * 0002 preptlist.c:180,206,316 tlist_member × 3 MERGE/UPDATE/RETURNING * 0003 equivclass.c:1041 list_member EC Var membership check * 0004 analyzejoins.c:1914 list_member join elimination merge * * For each site, benchmark runs the defective (O(n²)) and fixed (O(n)) * algorithms at increasing scale and reports wall-clock time and speedup. * * These are ALGORITHM MICRO-BENCHMARKS, not real PostgreSQL query timings. * Real query planning overhead includes catalog lookups, lock acquisition, * and other work that dominates at low N. The micro-benchmark isolates the * membership-check algorithm and represents the speedup ceiling for each site. */ public class PostgresqlBenchmark { static final int WARMUP_ROUNDS = 5; // ── 0002: preptlist.c — MERGE Var dedup ────────────────────────────────── static void bench0002() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" postgresql-0002 — preptlist.c tlist_member (MERGE/UPDATE/RETURNING)"); System.out.println(" tlist_member O(n²) → HashSet/Bitmapset O(n)"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-8s %-14s %-14s %-10s %s%n", "N vars", "Defective (ms)", "Fixed (ms)", "Speedup", "Tlist"); System.out.println(" " + "─".repeat(62)); for (int n : new int[]{20, 50, 100, 200, 500, 1000, 2000}) { List vars = PostgresqlVarDedupAlgorithm.buildVarPool(n, 1, n / 2); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { PostgresqlVarDedupAlgorithm.defectiveBuildTlist(vars, 1); PostgresqlVarDedupAlgorithm.fixedBuildTlist(vars, 1); } long t0 = System.nanoTime(); PostgresqlVarDedupAlgorithm.Result def = PostgresqlVarDedupAlgorithm.defectiveBuildTlist(vars, 1); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); PostgresqlVarDedupAlgorithm.Result fix = PostgresqlVarDedupAlgorithm.fixedBuildTlist(vars, 1); long fixNs = System.nanoTime() - t0; System.out.printf(" %-8d %-14.3f %-14.3f %-10.1fx %d%n", vars.size(), defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs), def.tlist.size()); } } // ── 0003: equivclass.c — EC member Var membership ──────────────────────── static void bench0003() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" postgresql-0003 — equivclass.c list_member (EC Var membership)"); System.out.println(" list_member O(|exprvars| × M × K) → HashSet O(|exprvars| + M × K)"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-12s %-14s %-14s %s%n", "|exprvars|", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(54)); Random rng = new Random(42); int emMembers = 30, emVarsEach = 6; for (int e : new int[]{10, 50, 100, 500, 1000, 2000, 5000}) { List exprvars = PostgresqlExprMembershipAlgorithm.buildExprList(e, 0); List members = PostgresqlExprMembershipAlgorithm.buildEcMembers(emMembers, emVarsEach, e, rng); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { PostgresqlExprMembershipAlgorithm.defectiveFindEm(exprvars, members); PostgresqlExprMembershipAlgorithm.fixedFindEm(exprvars, members); } long t0 = System.nanoTime(); PostgresqlExprMembershipAlgorithm.Result def = PostgresqlExprMembershipAlgorithm.defectiveFindEm(exprvars, members); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); PostgresqlExprMembershipAlgorithm.Result fix = PostgresqlExprMembershipAlgorithm.fixedFindEm(exprvars, members); long fixNs = System.nanoTime() - t0; System.out.printf(" %-12d %-14.3f %-14.3f %.1fx%n", e, defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── 0004: analyzejoins.c — join elimination reltarget merge ────────────── static void bench0004() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" postgresql-0004 — analyzejoins.c list_member (join elim merge)"); System.out.println(" list_member O(N × M) → HashSet O(N + M)"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-10s %-14s %-14s %s%n", "N=M exprs", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(54)); Random rng = new Random(42); for (int n : new int[]{10, 25, 50, 100, 200, 500, 1000}) { int overlap = n / 2; List keepExprs = new ArrayList<>(); for (int i = 0; i < n; i++) keepExprs.add(new PostgresqlJoinMergeAlgorithm.Expr(i)); List removeExprs = new ArrayList<>(); for (int i = 0; i < overlap; i++) removeExprs.add(new PostgresqlJoinMergeAlgorithm.Expr(i)); for (int i = n; i < n + (n - overlap); i++) removeExprs.add(new PostgresqlJoinMergeAlgorithm.Expr(i)); Collections.shuffle(removeExprs, rng); RelTarget toKeep = new RelTarget(keepExprs); RelTarget toRemove = new RelTarget(removeExprs); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { PostgresqlJoinMergeAlgorithm.defectiveMerge(toRemove, toKeep); PostgresqlJoinMergeAlgorithm.fixedMerge(toRemove, toKeep); } long t0 = System.nanoTime(); PostgresqlJoinMergeAlgorithm.Result def = PostgresqlJoinMergeAlgorithm.defectiveMerge(toRemove, toKeep); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); PostgresqlJoinMergeAlgorithm.Result fix = PostgresqlJoinMergeAlgorithm.fixedMerge(toRemove, toKeep); long fixNs = System.nanoTime() - t0; System.out.printf(" %-10d %-14.3f %-14.3f %.1fx%n", n, defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── Main ───────────────────────────────────────────────────────────────── public static void main(String[] args) { System.out.println(); System.out.println("╔══════════════════════════════════════════════════════════════════╗"); System.out.println("║ PostgresqlBenchmark — CWE-407 algorithm micro-benchmarks ║"); System.out.println("║ postgresql-0002 postgresql-0003 postgresql-0004 ║"); System.out.println("╠══════════════════════════════════════════════════════════════════╣"); System.out.println("║ All three sites: list membership O(n²) → hash set O(n) ║"); System.out.println("║ Fix path B: Bitmapset/HashMap on Var identity, no nodeHash() ║"); System.out.println("║ NOTE: algorithm isolation — not real PostgreSQL query timings ║"); System.out.println("╚══════════════════════════════════════════════════════════════════╝"); bench0002(); bench0003(); bench0004(); System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" SUMMARY"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" postgresql-0002 FIXABLE preptlist.c:180,206,316 — Path B"); System.out.println(" postgresql-0003 FIXABLE equivclass.c:1041 — Path B"); System.out.println(" postgresql-0004 FIXABLE analyzejoins.c:1914 — nodeHash()"); System.out.println(" postgresql-0001 DEFERRED tlist.c:812 — Path A"); System.out.println(" postgresql-0005 FIXABLE list.c ptr variants — Path B (ptr)"); System.out.println("══════════════════════════════════════════════════════════════════"); } }