java-topology/tests/bench/PostgresqlBenchmark.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

201 lines
11 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Var> 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<Expr> exprvars = PostgresqlExprMembershipAlgorithm.buildExprList(e, 0);
List<EquivalenceMember> 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<PostgresqlJoinMergeAlgorithm.Expr> keepExprs = new ArrayList<>();
for (int i = 0; i < n; i++)
keepExprs.add(new PostgresqlJoinMergeAlgorithm.Expr(i));
List<PostgresqlJoinMergeAlgorithm.Expr> 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("══════════════════════════════════════════════════════════════════");
}
}