Skip to content

perf: remove algorithmic compiler and layout cliffs - #2827

Merged
alixander merged 2 commits into
masterfrom
agent/algorithmic-performance
Aug 9, 2026
Merged

perf: remove algorithmic compiler and layout cliffs#2827
alixander merged 2 commits into
masterfrom
agent/algorithmic-performance

Conversation

@alixander

@alixander alixander commented Aug 9, 2026

Copy link
Copy Markdown
Collaborator

Uses github.com/d2lang/dagro v0.1.1, released from d2lang/dagro#2.

What

  • add ordered IR field/edge indexes while preserving safe public mutation semantics
  • replace global lazy-glob rescans with a deterministic incremental worklist
  • cache cloned import AST and context-safe IR templates
  • resolve D2 Dagre endpoints and parallel-edge counts once, cache container topology, and batch independent nested extraction
  • optimize Dagro's deep-compound ordering and layer-graph construction
  • replace ELK adapter/postprocessing rescans with graph indexes, subtree intervals, and an exact mutation-aware spatial broad phase
  • reuse layout geometry for style-only scenarios and steps under an explicit stable-resolver opt-in
  • document the performance work in the next changelog

Why

Removing the JavaScript runtimes exposed several older source-compatible algorithms that repeatedly scanned or copied the entire graph/IR. Large globs, repeated imports, nested containers, style-only boards, and bend-heavy layouts could therefore grow quadratically or worse.

Impact

Apple M4, one CPU, synthetic stress fixtures unless noted:

  • leading glob, 1,000 fields: 1.59 s → 12 ms (~133×)
  • repeated 100-field import, 100 uses: 54 ms → 12 ms (~4.6×)
  • 4,000 flat fields: 67 ms → 7 ms (~9.6×)
  • 3,200 distinct edges: 200 ms → 19 ms (~10.6×)
  • 32-node style-only diagram with 8 scenarios + 8 steps: 40 ms → 7.3 ms (~5.5×), ~81% fewer allocated bytes
  • nested D2 Dagre stress: ~32% faster
  • dense ELK 250-node/1,000-edge stress: ~30% faster
  • Dagro depth-100 compound stress: 3.60 s → 0.90 s (~4×), 73% fewer allocated bytes

These are targeted/pathological benchmarks rather than a corpus-weighted claim; ordinary diagrams primarily benefit by avoiding the specific cliffs.

Compatibility

  • exact D2 E2E SVG/layout corpus remains unchanged with reuse enabled
  • geometry reuse defaults off for arbitrary public d2lib layout resolvers; CLI/WASM opt in only for stable built-in resolution
  • sequence, grid, and constant-near layouts conservatively bypass reuse
  • public IR lookup/mutation APIs remain linear and safe for direct exported-slice mutation; only compiler-private paths use derived indexes
  • ELK keeps the original exact collision predicates and mutation order, with brute-force fallback for unsafe/huge coordinates
  • Dagro passes the upstream Dagre 0.8.5 differential corpus
  • IR fixture changes only remove duplicate internal source-reference records; compiled semantics and rendered output are unchanged

Validation

  • go test ./e2etests -run '^TestE2E$' -count=1 -parallel=1
  • go test -race ./... (all packages except three baseline-confirmed GIF CLI race/timing failures; exact E2E passes under race)
  • go vet ./...
  • GOOS=js GOARCH=wasm go build -trimpath ./d2js
  • focused wasm32 ELK compile
  • go mod tidy -diff
  • go mod verify
  • independent compiler and layout correctness reviews

Signed-off-by: Alexander Wang <alex@terrastruct.com>
Signed-off-by: Alexander Wang <alex@terrastruct.com>
@alixander
alixander marked this pull request as ready for review August 9, 2026 23:35
@alixander
alixander merged commit 6844d24 into master Aug 9, 2026
6 checks passed
@alixander
alixander deleted the agent/algorithmic-performance branch August 9, 2026 23:38
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