GitHub
09/04/2026, 11:57 AMsrc/backend/executor/nodeRuntimeFilter.c) uses
bloom_create_aggresive() (bloomfilter.c), and its choices are the opposite
of Anser's:
| Anser (bloom_create) | core RF (bloom_create_aggresive) | |
| -------------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| bits per key | 16 | 9 (total_elems * 9 / 8 bytes) |
| floor / cap | 1 MB / 64 MB | 128 KB / 2 MB |
| hash functions | up to 10 (optimal_k) | 2 or 3, hard-coded, "balance false positive rate and calculation costs" |
| refuses to build | never | when bits_per_elem < 1.6 → returns NULL, "too many elements" |
| abandons mid-build | never | yes: inner_threshold = bloom_total_bits(bf) / 1.6, then build_suspend = true (nodeRuntimeFilter.c:246,311) |
Start every task by explaining why Anser differs from this, and treat the
aggressive profile as a candidate answer that someone in this codebase already
committed to. Do not invent new thresholds before measuring against that one.
How to produce results we can act on
This section is the actual hard part of this issue. Results that don't follow
it will be sent back, not because of process for its own sake, but because we
cannot make a shipping decision from them.
1. Build discipline (most common way to waste a week)
• Never benchmark a build configured with --enable-cassert or
--enable-debug only. Assertions make PostgreSQL 20-40% slower and
distort exactly the kind of tight loop you are measuring. Configure a
separate optimized build (-O2, no cassert) and paste the configure
line into your report.
• Record the compiler and version. Auto-vectorization differs between GCC and
Clang and between versions; a result without a compiler version is not
reproducible.
• Pin a baseline commit hash and re-measure the baseline in the same session
as the variant. Never compare against numbers from yesterday's machine state.
2. Measure at two layers, always both
| Layer | How | Answers |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
| Micro | a SQL-callable C benchmark added to gpcontrib/anser/src/anser_test.c (follow the existing anser_test_bloom_* helpers), e.g. anser_test_bench_fold(bytes, iters) returning elapsed ms | "is the OR faster?" |
| End-to-end | query wall time on a demo/real cluster, TPC-DS with SF=100 | "does the query get faster?" |
A micro-benchmark win that does not move end-to-end time is a negative
result — report it as such. That happens constantly and is fine.
Keep benchmark helpers out of the regression expected output; they are
nondeterministic. They are for manual runs.
Notes about TPC-DS
Scale factor 100 minimum. SF 1 and SF 10 are not acceptable evidence: the
tables fit in memory, the filter is pure overhead, and the result tells us
nothing about production. Use SF 1000 if the hardware allows, and state the
cluster shape (hosts × segments per host).
You could use special extension to run TPC-DS https://github.com/avamingli/pg_tpcds
Step 1 — find out which queries Anser even touches. The plan pass only
injects into one join shape, so most of the 99 queries will be untouched and
their timings are noise. Establish the injected subset first:
Report that list — it is a result in its own right, and if it is empty, stop and
open a bug instead of benchmarking. Expect the star-schema fact/dimension joins
(q3, q7, q13, q17, q19, q25, q29, q42, q43, q46, q52, q55, q64, q68, q72, q79,
q88, q96, q98 are the usual candidates), but use your measured list, not
this one.
Step 2 — run the full suite, 3 iterations, `anser.runtime_fi
on, everything else identical. Report per-query medians.
Step 3 — report in three parts:
1. Injected queries — the detail table:
| Query | baseline (s) | variant (s) | Δ% | consumer wait (ms) |
| --- | --- | --- | --- | --- | --- |
| q19 | | | | | |
1. Non-injected queries — one line: worst regression observed,
of que…
apache/cloudberry