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
perf: speed up LP file writing (2.5-3.9x on large models, no regressions on small) (#564)
* perf: use Polars streaming engine for LP file writing
Extract _format_and_write() helper that uses lazy().collect(engine="streaming")
with automatic fallback, replacing 7 instances of df.select(concat_str(...)).write_csv(...).
* fix: log warning with traceback when Polars streaming fallback triggers
* perf: speed up LP constraint writing by replacing concat+sort with join
Replace the vertical concat + sort approach in Constraint.to_polars()
with an inner join, so every row has all columns populated. This removes
the need for the group_by validation step in constraints_to_file() and
simplifies the formatting expressions by eliminating null checks on
coeffs/vars columns.
* fix: missing space in lp file
* perf: skip group_terms when unnecessary and avoid xarray broadcast for short DataFrame
- Skip group_terms_polars when _term dim size is 1 (no duplicate vars)
- Build the short DataFrame (labels, rhs, sign) directly with numpy
instead of going through xarray.broadcast + to_polars
- Add sign column via pl.lit when uniform (common case), avoiding
costly numpy string array → polars conversion
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* perf: skip group_terms in LinearExpression.to_polars when no duplicate vars
Check n_unique before running the expensive group_by+sum. When all
variable references are unique (common case for objectives), this
saves ~31ms per 320k terms.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* perf: reduce per-constraint overhead in Constraint.to_polars()
Replace np.unique with faster numpy equality check for sign uniformity.
Eliminate redundant filter_nulls_polars and check_has_nulls_polars on
the short DataFrame by applying the labels mask directly during
construction.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: handle empty constraint slices in sign_flat check
Guard against IndexError when sign_flat is empty (no valid labels)
by checking len(sign_flat) > 0 before accessing sign_flat[0].
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add LP write speed improvement to release notes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* bench: add LP write benchmark script with plotting
* bench: larger model
* perf: Add maybe_group_terms_polars() helper in common.py that checks for duplicate (labels, vars) pairs before calling group_terms_polars. Use it in both Constraint.to_polars() and LinearExpression.to_polars() to avoid expensive group_by when terms already reference distinct variables
* Add variance to plot
* test: add coverage for streaming fallback and maybe_group_terms_polars
* fix: mypy
* fix: mypy
* Move kwargs into method for readability
* Remove fallback and pin polars >=1.31
* Remove the benchmark_lp_writer.py
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: doc/release_notes.rst
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,7 @@ Upcoming Version
6
6
7
7
* Fix docs (pick highs solver)
8
8
* Add the `sphinx-copybutton` to the documentation
9
+
* Speed up LP file writing by 2-2.7x on large models through Polars streaming engine, join-based constraint assembly, and reduced per-constraint overhead
0 commit comments