You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following content was generated by AI (Claude Code) during the review of #929, verified by @FabianHofmann.
Since #929, CSRConstraint stores raw variable labels as CSR columns and maps them to dense positions at matrix assembly (CSRConstraint._to_positional_csr). That mapping allocates a fresh indices array on every call, so the persistent snapshot diff (linopy/persistent/diff.py, _same) can no longer short-circuit on array identity for indices and falls through to a full np.array_equal over all non-zeros. data and indptr keep their identity, so the rest of the fast path survives.
Measured on a frozen model with about 600k non-zeros: the gather plus compare costs about 4.5 ms of a 36 ms diff, roughly 12%.
Proposal
Cache the positional CSR on the constraint, keyed on the VariableLabelIndex (or its invalidation counter), so repeated to_matrix / to_matrix_with_rhs calls without variable changes return the same indices buffer. Constraints._invalidate_label_position_index and the variable container's invalidation are the natural hooks.
Note
The following content was generated by AI (Claude Code) during the review of #929, verified by @FabianHofmann.
Since #929,
CSRConstraintstores raw variable labels as CSR columns and maps them to dense positions at matrix assembly (CSRConstraint._to_positional_csr). That mapping allocates a freshindicesarray on every call, so the persistent snapshot diff (linopy/persistent/diff.py,_same) can no longer short-circuit on array identity forindicesand falls through to a fullnp.array_equalover all non-zeros.dataandindptrkeep their identity, so the rest of the fast path survives.Measured on a frozen model with about 600k non-zeros: the gather plus compare costs about 4.5 ms of a 36 ms diff, roughly 12%.
Proposal
Cache the positional CSR on the constraint, keyed on the
VariableLabelIndex(or its invalidation counter), so repeatedto_matrix/to_matrix_with_rhscalls without variable changes return the sameindicesbuffer.Constraints._invalidate_label_position_indexand the variable container's invalidation are the natural hooks.Follow-up to #926 / #929.