Skip to content

ci(codspeed): pin polars to one thread in the memory job - #980

Merged
FabianHofmann merged 3 commits into
masterfrom
ci/codspeed-polars-single-thread
Sep 25, 2026
Merged

FabianHofmann merged 3 commits into
masterfrom
ci/codspeed-polars-single-thread

Conversation

@FabianHofmann

Copy link
Copy Markdown
Collaborator

Note

The following content was generated by AI.

Sets POLARS_MAX_THREADS=1 on the CodSpeed memory job.

Polars allocates native memory per worker thread, so the peak memory of the polars-based benchmarks (e.g. test_to_lp) depends on the core count of the ubuntu-latest runner. That produced a false regression on #974 (test_to_lp[nodal_balance-severity=0], 3.3 → 3.7 MB), for a legacy dense model that the PR's code does not touch.

Measurements (master 38fbd4a vs feat/csr-boundaries a817a5e, write_lp only)
  • tracemalloc (Python heap), nodal_balance: 0.959 MB on both after the first call.
  • memray with POLARS_MAX_THREADS=1: peaks and total allocations identical byte for byte across revisions and repeated processes.
  • memray with the default thread pool: the same revision swings between 3.5 and 12.8 MB across processes.

The walltime job is left untouched, since thread parallelism there is part of what is measured.

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Build cost — v1 vs legacy

v1 build peak & time relative to legacy, on this commit — not a comparison against master (that is CodSpeed).

peak — v1 / legacy time — v1 / legacy
peak v1/legacy time v1/legacy
Full table (time + peak, mean)
benchmarks/drivers/test_build.py::test_build[basic-n=10]
                 time (s)         peak (KiB) 
 name                mean   │           mean 
─────────────────────────────────────────────
 (legacy)   0.0906 (1.07)   │   15.03 (1.00) 
 (v1)       0.08449 (1.0)   │    15.00 (1.0) 

benchmarks/drivers/test_build.py::test_build[basic-n=250]
                  time (s)         peak (MiB) 
 name                 mean   │           mean 
──────────────────────────────────────────────
 (legacy)   0.09676 (1.10)   │   12.04 (1.00) 
 (v1)        0.08824 (1.0)   │    12.04 (1.0) 

benchmarks/drivers/test_build.py::test_build[cumsum-severity=0]
                  time (s)        peak (KiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.03878 (1.08)   │   15.20 (1.0) 
 (v1)         0.0358 (1.0)   │   15.20 (1.0) 

benchmarks/drivers/test_build.py::test_build[cumsum-severity=100]
                  time (s)        peak (MiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.05528 (1.05)   │   44.93 (1.0) 
 (v1)        0.05253 (1.0)   │   44.93 (1.0) 

benchmarks/drivers/test_build.py::test_build[cumsum-severity=50]
                  time (s)        peak (MiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.04195 (1.08)   │   11.51 (1.0) 
 (v1)        0.03899 (1.0)   │   11.51 (1.0) 

benchmarks/drivers/test_build.py::test_build[expression_arithmetic-n=10]
                 time (s)         peak (KiB) 
 name                mean   │           mean 
─────────────────────────────────────────────
 (legacy)    0.101 (1.06)   │   24.34 (1.06) 
 (v1)       0.09555 (1.0)   │    23.04 (1.0) 

benchmarks/drivers/test_build.py::test_build[expression_arithmetic-n=250]
                 time (s)         peak (MiB) 
 name                mean   │           mean 
─────────────────────────────────────────────
 (legacy)   0.1104 (1.06)   │   16.12 (1.00) 
 (v1)        0.1038 (1.0)   │    16.12 (1.0) 

benchmarks/drivers/test_build.py::test_build[knapsack-n=10000]
                  time (s)          peak (KiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.02392 (1.06)   │   752.18 (1.10) 
 (v1)        0.02255 (1.0)   │    685.15 (1.0) 

benchmarks/drivers/test_build.py::test_build[knapsack-n=100]
                  time (s)        peak (KiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.02334 (1.05)   │   3.12 (1.33) 
 (v1)        0.02214 (1.0)   │    2.34 (1.0) 

benchmarks/drivers/test_build.py::test_build[kvl_cycles-severity=0]
                  time (s)          peak (MiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.06334 (1.20)   │   126.16 (1.44) 
 (v1)         0.0527 (1.0)   │     87.71 (1.0) 

benchmarks/drivers/test_build.py::test_build[kvl_cycles-severity=100]
                  time (s)          peak (MiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.06294 (1.21)   │   126.16 (1.44) 
 (v1)        0.05201 (1.0)   │     87.71 (1.0) 

benchmarks/drivers/test_build.py::test_build[kvl_cycles-severity=50]
                  time (s)          peak (MiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.06305 (1.21)   │   126.16 (1.44) 
 (v1)        0.05223 (1.0)   │     87.71 (1.0) 

benchmarks/drivers/test_build.py::test_build[masked-n=100]
                  time (s)          peak (KiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.05499 (1.00)   │    715.12 (1.0) 
 (v1)        0.05487 (1.0)   │   787.73 (1.10) 

benchmarks/drivers/test_build.py::test_build[masked-n=10]
                  time (s)        peak (KiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.05311 (1.07)   │   4.54 (1.27) 
 (v1)        0.04973 (1.0)   │    3.57 (1.0) 

benchmarks/drivers/test_build.py::test_build[merge_balance-severity=0]
                 time (s)          peak (KiB) 
 name                mean   │            mean 
──────────────────────────────────────────────
 (legacy)   0.3793 (1.02)   │   704.12 (1.09) 
 (v1)        0.3719 (1.0)   │    643.85 (1.0) 

benchmarks/drivers/test_build.py::test_build[merge_balance-severity=100]
                 time (s)        peak (MiB) 
 name                mean   │          mean 
────────────────────────────────────────────
 (legacy)   0.4024 (1.03)   │   18.34 (1.0) 
 (v1)         0.392 (1.0)   │   18.34 (1.0) 

benchmarks/drivers/test_build.py::test_build[merge_balance-severity=50]
                 time (s)       peak (MiB) 
 name                mean   │         mean 
───────────────────────────────────────────
 (legacy)   0.3941 (1.03)   │   9.54 (1.0) 
 (v1)        0.3843 (1.0)   │   9.54 (1.0) 

benchmarks/drivers/test_build.py::test_build[milp-n=10]
                  time (s)        peak (KiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.07484 (1.07)   │   3.77 (1.12) 
 (v1)        0.06987 (1.0)   │    3.37 (1.0) 

benchmarks/drivers/test_build.py::test_build[milp-n=50]
                 time (s)          peak (KiB) 
 name                mean   │            mean 
──────────────────────────────────────────────
 (legacy)   0.0766 (1.08)   │   216.59 (1.10) 
 (v1)       0.07097 (1.0)   │    196.23 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance-severity=0]
                  time (s)         peak (KiB) 
 name                 mean   │           mean 
──────────────────────────────────────────────
 (legacy)   0.03897 (1.11)   │   938.49 (1.0) 
 (v1)        0.03499 (1.0)   │   938.49 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance-severity=100]
                  time (s)       peak (MiB) 
 name                 mean   │         mean 
────────────────────────────────────────────
 (legacy)   0.03973 (1.09)   │   9.66 (1.0) 
 (v1)        0.03651 (1.0)   │   9.66 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance-severity=50]
                 time (s)       peak (MiB) 
 name                mean   │         mean 
───────────────────────────────────────────
 (legacy)   0.0394 (1.10)   │   5.32 (1.0) 
 (v1)       0.03573 (1.0)   │   5.32 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance_sparse-severity=0]
                  time (s)       peak (MiB) 
 name                 mean   │         mean 
────────────────────────────────────────────
 (legacy)    0.02192 (1.0)   │   1.28 (1.0) 
 (v1)       0.02206 (1.01)   │   1.28 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance_sparse-severity=100]
                  time (s)       peak (MiB) 
 name                 mean   │         mean 
────────────────────────────────────────────
 (legacy)    0.02132 (1.0)   │   1.28 (1.0) 
 (v1)       0.02138 (1.00)   │   1.28 (1.0) 

benchmarks/drivers/test_build.py::test_build[nodal_balance_sparse-severity=50]
                  time (s)       peak (MiB) 
 name                 mean   │         mean 
────────────────────────────────────────────
 (legacy)     0.0212 (1.0)   │   1.28 (1.0) 
 (v1)       0.02134 (1.01)   │   1.28 (1.0) 

benchmarks/drivers/test_build.py::test_build[piecewise-n=1000]
                 time (s)          peak (KiB) 
 name                mean   │            mean 
──────────────────────────────────────────────
 (legacy)   0.1901 (1.04)   │   946.85 (1.06) 
 (v1)        0.1822 (1.0)   │    891.54 (1.0) 

benchmarks/drivers/test_build.py::test_build[piecewise-n=10]
                 time (s)         peak (KiB) 
 name                mean   │           mean 
─────────────────────────────────────────────
 (legacy)   0.1858 (1.05)   │   12.01 (1.00) 
 (v1)        0.1764 (1.0)   │    11.99 (1.0) 

benchmarks/drivers/test_build.py::test_build[qp-n=1000]
                 time (s)          peak (KiB) 
 name                mean   │            mean 
──────────────────────────────────────────────
 (legacy)   0.0475 (1.06)   │   147.70 (1.06) 
 (v1)       0.04478 (1.0)   │    139.87 (1.0) 

benchmarks/drivers/test_build.py::test_build[qp-n=10]
                  time (s)        peak (KiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.04734 (1.06)   │   2.60 (1.09) 
 (v1)        0.04475 (1.0)   │    2.38 (1.0) 

benchmarks/drivers/test_build.py::test_build[rolling-severity=0]
                  time (s)          peak (KiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.03986 (1.09)   │   696.75 (1.03) 
 (v1)        0.03657 (1.0)   │    673.70 (1.0) 

benchmarks/drivers/test_build.py::test_build[rolling-severity=100]
                  time (s)         peak (MiB) 
 name                 mean   │           mean 
──────────────────────────────────────────────
 (legacy)   0.08267 (1.01)   │   137.97 (1.0) 
 (v1)        0.08169 (1.0)   │   137.97 (1.0) 

benchmarks/drivers/test_build.py::test_build[rolling-severity=50]
                  time (s)        peak (MiB) 
 name                 mean   │          mean 
─────────────────────────────────────────────
 (legacy)   0.06078 (1.09)   │   69.22 (1.0) 
 (v1)        0.05573 (1.0)   │   69.22 (1.0) 

benchmarks/drivers/test_build.py::test_build[sos-n=1000]
                  time (s)          peak (KiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)   0.04544 (1.10)   │   402.33 (1.00) 
 (v1)        0.04148 (1.0)   │    402.30 (1.0) 

benchmarks/drivers/test_build.py::test_build[sos-n=10]
                 time (s)        peak (KiB) 
 name                mean   │          mean 
────────────────────────────────────────────
 (legacy)   0.0443 (1.08)   │   3.19 (1.19) 
 (v1)         0.041 (1.0)   │    2.69 (1.0) 

benchmarks/drivers/test_build.py::test_build[sparse_network-n=10]
                  time (s)         peak (KiB) 
 name                 mean   │           mean 
──────────────────────────────────────────────
 (legacy)   0.04975 (1.07)   │   29.00 (1.54) 
 (v1)         0.0463 (1.0)   │    18.84 (1.0) 

benchmarks/drivers/test_build.py::test_build[sparse_network-n=250]
                  time (s)         peak (MiB) 
 name                 mean   │           mean 
──────────────────────────────────────────────
 (legacy)   0.05932 (1.08)   │   37.95 (1.43) 
 (v1)        0.05475 (1.0)   │    26.51 (1.0) 

benchmarks/drivers/test_build.py::test_build[storage-n=10]
                  time (s)          peak (KiB) 
 name                 mean   │            mean 
───────────────────────────────────────────────
 (legacy)    0.09351 (1.0)   │    410.93 (1.0) 
 (v1)       0.09746 (1.04)   │   427.84 (1.04) 

benchmarks/drivers/test_build.py::test_build[storage-n=250]
                 time (s)         peak (MiB) 
 name                mean   │           mean 
─────────────────────────────────────────────
 (legacy)   0.09904 (1.0)   │     9.94 (1.0) 
 (v1)       0.1048 (1.06)   │   10.22 (1.03) 

📊 Interactive plots + CSV: download the semantics-report-v1-vs-legacy artifact from this run.

Report-only · not a gate · refreshed on every push · obsolete once legacy is dropped.

@codspeed

codspeed Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Merging this PR will regress 1 benchmark

⚡ 16 improved benchmarks
❌ 1 regressed benchmark
✅ 164 untouched benchmarks
⏩ 181 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_to_lp[expression_arithmetic-n=250] 42.8 MB 50.1 MB -14.59%
⚡ test_to_lp[qp-n=1000] 2,646.5 KB 795.3 KB ×3.3
⚡ test_to_lp[masked-n=100] 2,793.7 KB 892.7 KB ×3.1
⚡ test_to_lp[milp-n=50] 2,760 KB 885.3 KB ×3.1
⚡ test_to_lp[sos-n=1000] 3 MB 1.4 MB ×2.2
⚡ test_to_lp[expression_arithmetic-n=10] 1,339.1 KB 691.1 KB +93.76%
⚡ test_to_lp[sparse_network-n=10] 1,337.7 KB 695.6 KB +92.3%
⚡ test_to_lp[storage-n=10] 2.9 MB 1.6 MB +78.9%
⚡ test_to_lp[piecewise-n=1000] 3 MB 1.9 MB +60.75%
⚡ test_to_lp[rolling-severity=0] 3.1 MB 2 MB +57.33%
⚡ test_to_lp[cumsum-severity=50] 62.3 MB 43.1 MB +44.74%
⚡ test_to_lp[knapsack-n=10000] 3 MB 2.1 MB +40.41%
⚡ test_to_lp[cumsum-severity=100] 208.9 MB 160.9 MB +29.83%
⚡ test_to_lp[rolling-severity=50] 429.9 MB 333.9 MB +28.76%
⚡ test_to_lp[rolling-severity=100] 274.6 MB 227 MB +20.97%
⚡ test_to_lp[kvl_cycles-severity=0] 280.9 MB 232.9 MB +20.61%
⚡ test_to_lp[kvl_cycles-severity=50] 141.6 MB 117.6 MB +20.41%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing ci/codspeed-polars-single-thread (22e8fdf) with master (14f601e)2

Open in CodSpeed

Footnotes

  1. 181 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

  2. No successful run was found on master (1a355c1) during the generation of this report, so 14f601e was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@FabianHofmann
FabianHofmann merged commit bee7d1f into master Sep 25, 2026
20 of 21 checks passed
@FabianHofmann
FabianHofmann deleted the ci/codspeed-polars-single-thread branch September 25, 2026 06:03
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