Skip to content

perf: two quadratic passes in model creation, and three smaller costs - #333

Open
bvdmitri wants to merge 1 commit into
4.9.0from
perf/quadratic-constraints-and-meta
Open

bvdmitri wants to merge 1 commit into
4.9.0from
perf/quadratic-constraints-and-meta

Conversation

@bvdmitri

Copy link
Copy Markdown
Member

What

Five non-breaking fixes to model creation. The results are unchanged: the existing tests pass untouched.

change where measured
apply_meta! walks the context's own factor nodes, not every node of the model filtered by membership in the context plugins/meta/meta_engine.jl it was quadratic, 84% of creation with @algorithm: nonlinear SSM at n = 3 000, 4.51 → 0.47 s
while constraints are applied, flattened_index of a matrix variable uses prefix sums cached per array (with_flattened_index_cache, cached_flattened_index), bound around apply_constraints! resizable_array.jl, variational_constraints*.jl matrix-variable constraints were quadratic (19 s at 10⁵ elements): 3.07 → 0.81 s at 4·10⁴
NodeLabel == compares the Int counter first graph_engine.jl 30 → 19 ns per lookup
the factorisation bitsets start as the full joint, built directly, and a node with no factorisation skips the partition step variational_constraints*.jl graph stage 10–13% faster on an HMM and an iid model
ConstraintStack keeps a Vector, read from the top as the Stack was variational_constraints_engine.jl DataStructures.Stack allocated a 1 024-element block per model: 12–29% of a tiny model's infer

These were measured as part of ReactiveMP's end-of-refactor performance pass (Julia 1.13, M-series Mac). The cache uses task_local_storage as a dynamic scope, since ScopedValue is Base only from Julia 1.11 and GraphPPL supports 1.10.

Tests

  • New: cached_flattened_index agrees with flattened_index on a ragged 3-D array, with and without the cache, and on a 1-D one; ConstraintStack reads from the top, keeps its per-context counts and pops per context (it gains length and eltype).
  • make test: 76 878 pass, 1 broken as before.
  • Not reformatted: make lint also reports 12 files on 4.9.0 itself, and formatting the touched files would rewrite unrelated code.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Re8DzeAcZpjeENCE44QJjF

- apply_meta! walked every node of the model for every meta entry, and kept
  those in the context: quadratic in the model's size with @meta or
  @Algorithm. It walks the context's own factor nodes.
- Resolving a constraint on a matrix variable summed the lengths of every
  slice before an index for each element, quadratic in the variable's size.
  While constraints are applied, the plugin binds a cache of those prefix
  sums per array (with_flattened_index_cache, cached_flattened_index).
- NodeLabel == compares the counter first, an Int unique per node, before the
  untyped name.
- The factorisation bitsets start as the full joint, built directly, and a
  node with no factorisation at all skips the partition step.
- ConstraintStack keeps its constraints in a Vector read from the top, where
  DataStructures' Stack allocated a 1024-element block for every model; it
  gains length and eltype.

Tests: cached_flattened_index against flattened_index on a ragged array, with
and without the cache; ConstraintStack's order, counts and pops.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Re8DzeAcZpjeENCE44QJjF
@bvdmitri
bvdmitri requested a review from wouterwln September 28, 2026 14:29
@codecov

codecov Bot commented Sep 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.28%. Comparing base (849fd25) to head (0a3ec0a).

Additional details and impacted files
@@            Coverage Diff             @@
##            4.9.0     #333      +/-   ##
==========================================
+ Coverage   91.04%   91.28%   +0.23%     
==========================================
  Files          16       16              
  Lines        2301     2318      +17     
==========================================
+ Hits         2095     2116      +21     
+ Misses        206      202       -4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch has not been deployed

No deployments
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