Skip to content

perf: precompute constraint arrays for device_scheduler callbacks#2291

Draft
Flix6x wants to merge 2 commits into
mainfrom
perf/precompute-scheduler-constraint-arrays
Draft

perf: precompute constraint arrays for device_scheduler callbacks#2291
Flix6x wants to merge 2 commits into
mainfrom
perf/precompute-scheduler-constraint-arrays

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 11, 2026

Copy link
Copy Markdown
Member

Description

Speed up device_scheduler model construction by precomputing plain numpy arrays (and a j -> quantity dict per commitment) for the constraint columns, instead of doing per-index pandas lookups inside Pyomo initialize callbacks.

Pyomo calls each Param/Set initialize callback once per index tuple, so a pandas .iloc scalar lookup (or worse, a boolean-mask filter as in commitment_quantity_select) inside a callback costs O(devices × timesteps) individual slow pandas accesses. Indexing into precomputed numpy arrays yields identical values (NaN semantics preserved via float dtype) at a fraction of the cost.

Complementary to #2282 (recursive stock balance): that one speeds up constraint expression construction, this one speeds up parameter initialization.

Notes

  • Adapted to the device-groups structure from Feat: scheduler support for device groups #1934: EMS derivative arrays are precomputed per constraint group (ems_derivative_max_arr[g][j]).
  • The absent-column case for the efficiency columns (previously a try/except KeyError) is now an explicit None sentinel meaning "assume perfect efficiency".
  • No behavioural change intended; flexmeasures/data/models/planning/tests/test_solver.py (128 passed, 3 xfailed) and test_commitments.py (14 passed) pass locally.

To do before undrafting

  • Add changelog entry
  • Benchmark on a realistic multi-device schedule to quantify the speedup

🤖 Generated with Claude Code

https://claude.ai/code/session_01Pxkeq64jtENY7fiWjwUsVS

Pyomo calls each Param/Set initialize callback once per index tuple, so
per-index pandas .iloc and boolean-mask lookups cost
O(devices x timesteps) slow scalar accesses. Precompute plain numpy
arrays (and a j -> quantity dict per commitment) once and index into
those instead, preserving NaN semantics via float dtype.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxkeq64jtENY7fiWjwUsVS
@read-the-docs-community

read-the-docs-community Bot commented Jul 11, 2026

Copy link
Copy Markdown

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxkeq64jtENY7fiWjwUsVS
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