Skip to content

Distributed perf hardening: 3-12x faster fan-out and merge - #33

Merged
cigrainger merged 2 commits into
mainfrom
chore/perf-hardening
Mar 25, 2026
Merged

cigrainger merged 2 commits into
mainfrom
chore/perf-hardening

Conversation

@cigrainger

Copy link
Copy Markdown
Contributor

Summary

Performance

  • ordered: false in batch fan_out — the streaming path already used ordered: false, but the batch path forced sequential collection. Results are partitioned into success/failure post-hoc, so ordering is irrelevant. This is the biggest win.
  • Adaptive broadcast threshold — scales with worker count (threshold / n_workers) so total network cost stays constant regardless of cluster size. 2 workers: 128MB each. 10 workers: 25MB each.

Correctness

  • Regex-based aggregate detection in merger — replaces String.contains? with \b-anchored regex module attributes. Prevents COUNT_DISTINCT( matching the COUNT( branch.
  • FLAME pg polling — replaces Process.sleep(100) race condition with :pg.get_members polling loop (10ms interval, 5s timeout).

Benchmark Results (2 local workers, 100K rows)

Benchmark Before (median) After (median) Speedup
Distributed filter+agg 99ms 27ms 3.6x
Streaming SUM+COUNT merge 491ms 39ms 12.5x
Streaming MIN+MAX merge 64ms 16ms 3.9x
Broadcast join (100K × 20) 112ms 32ms 3.5x

Full benchmark results in bench/results/.

Test plan

  • 635 tests pass, 0 failures
  • Credo strict clean
  • Benchmarks recorded before and after

🤖 Generated with Claude Code

cigrainger and others added 2 commits March 25, 2026 11:38
…olling, regex agg

Performance:
- fan_out uses ordered: false (streaming path already did) — 3.6x faster
  median for distributed filter+agg (99ms → 27ms)
- Broadcast threshold scales with worker count (total network stays constant)

Correctness:
- Merger uses word-boundary regex for aggregate detection instead of
  String.contains? — prevents COUNT_DISTINCT matching COUNT branch
- FLAME spin_up replaces Process.sleep(100) with :pg.get_members
  polling loop (10ms interval, 5s timeout)

Benchmark results (2 local workers, 100K rows):
  distributed filter+agg: 99ms → 27ms (3.6x)
  streaming SUM+COUNT:   491ms → 39ms (12.5x)
  streaming MIN+MAX:      64ms → 16ms (3.9x)
  broadcast join:        112ms → 32ms (3.5x)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Regex structs contain references that can't be injected into module
attributes on all OTP/Elixir versions. Use inline cond with ~r// sigils
instead — they're still compiled at compile time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cigrainger
cigrainger merged commit 1842596 into main Mar 25, 2026
5 checks passed
@cigrainger
cigrainger deleted the chore/perf-hardening branch March 25, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant