Skip to content

Support for abi3 and forthcoming abi3t - #697

Merged
FrancescAlted merged 7 commits into
mainfrom
abi3
Aug 11, 2026
Merged

Support for abi3 and forthcoming abi3t#697
FrancescAlted merged 7 commits into
mainfrom
abi3

Conversation

@FrancescAlted

Copy link
Copy Markdown
Member

No description provided.

FrancescAlted and others added 5 commits August 11, 2026 08:47
Set wheel.py-api = "cp311" so scikit-build-core tags the wheel cp311-abi3,
and turn the SKBUILD_SABI_* variables it exports into USE_SABI on each
extension target.  USE_SABI defines Py_LIMITED_API, which is what flips
Cython into CYTHON_LIMITED_API mode, and together with WITH_SOABI names the
modules <name>.abi3.so.  A plain cmake invocation sets neither variable, so
the version-specific behaviour is unchanged outside of a wheel build.

No .pyx changes were needed.  The cdef classes (SChunk, vlmeta) build as
PyType_FromSpec heap types, the legacy `np.ndarray[dtype, ndim=N]` buffer
syntax in indexing_ext still compiles, and utf8_ext's NpyString usage is
limited-API clean, all with Cython 3.2.9 and NumPy 2.5.

Measured on macOS arm64, 4 interleaved runs, min-of-7 per measurement: worst
case 1.013x (compress2 of 8 KB buffers, i.e. call-overhead bound), everything
else within noise.  SChunk attribute access -- the most direct probe of the
heap-type path -- came out at 0.987x.  Full suite passes on the build
interpreter (3.14) and, using that same wheel, on 3.11/3.12/3.13.

Free-threaded builds keep their own version-specific wheels: scikit-build-core
ignores py-api when Py_GIL_DISABLED is set, so cp314t/cp315t need no extra
configuration.  Collapsing those into one wheel needs abi3t (PEP 803), which
starts at 3.15 and requires a PEP 793 module export hook that Cython cannot
emit yet.  So this is 7 wheels per platform down to 3, not 2.

Since the abi3 wheel is built only on 3.11 and cibuildwheel tests a wheel just
on the interpreter that produced it, add test_abi3_matrix: it installs the
single wheel on 3.11-3.15 across all three OSes, asserts the .abi3. module is
the one loaded, and runs a slice of the suite.  That is also the job that would
catch a future CPython breaking the stable ABI -- the risk abi3 takes on in
exchange for not rebuilding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Windows legs of test_abi3_matrix failed on all five Python versions while
the wheel builds and the Linux/macOS legs passed.  The wheel was fine: the
install step succeeded and only the assertion step failed.

".abi3." is a POSIX naming convention.  On Windows a limited-API extension is
just `blosc2_ext.pyd`, against `blosc2_ext.cp314-win_amd64.pyd` for a
version-specific build -- there is no abi3 infix to look for.

Check the portable invariant instead: importlib's EXTENSION_SUFFIXES[0] is the
version-tagged suffix on every platform, so an abi3 module is exactly the one
whose filename does not end with it.  Verified locally against both a normal
and an abi3 build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The benchmarking behind the abi3 switch covered exactly one cell: macOS
arm64, CPython 3.14, Apple clang.  That is thin evidence for a change whose
whole mechanism is platform-dependent.

The generated C is byte-identical between the two builds -- CYTHON_LIMITED_API
is a preprocessor macro, so the divergence happens entirely in the C compiler.
It is not a small divergence: the abi3 objects are 3-10% smaller (blosc2_ext
-10.2%) because Cython's inlined fast paths become calls into libpython.  So
abi3 moves work onto libpython calls, and the cost of such a call is not the
same everywhere.

Windows is the cell that matters.  There an abi3 extension links python3.dll,
a forwarder DLL, so each of those newly-added calls takes an extra thunk into
python3XY.dll.  POSIX has no equivalent -- symbols resolve straight from the
loaded interpreter.  3.11 and 3.14 are both built because one abi3 binary
serves the whole range while the interpreter-side handling differs by version.

Rounds are interleaved abi3/base/abi3/... so a slow patch on a shared runner
hits both builds instead of biasing whichever ran first, and the threshold is
a deliberately loose 1.25x: this environment can resolve an extra indirection
on every call, not a 3% difference.  Benchmarks under 5 ms are reported but
never fail the job.

The report is posted as a PR comment because job logs and step summaries are
not readable through the public API without admin rights.

Also extends the benchmark to the paths the local run skipped: utf8 ingest,
group_by+agg, multi-key group_by and where() over a 200k-row CTable, which is
what actually exercises utf8_ext, groupby_ext and indexing_ext.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ssion"

All six bench cells failed at "Create both environments" while every build
step, Windows included, succeeded.  The cause was

    PY=$(ls venv-$v/bin/python venv-$v/Scripts/python.exe 2>/dev/null | head -1)

GitHub runs `shell: bash` as `bash --noprofile --norc -eo pipefail`, so `set -e`
is active, and an assignment takes the exit status of its command substitution.
One of those two paths is always absent -- that is the whole point of listing
both -- so ls exits 2 and kills the step.  Replaced with an explicit -x test at
both call sites.

Also stop conflating outcomes in compare.py.  It exited 1 both when a benchmark
regressed and when no artifacts existed at all, so this run reported a
performance regression when what actually happened was that no benchmark ever
ran.  It now always exits 0 and publishes status=ok|regressed|nodata through
GITHUB_OUTPUT, with the workflow failing on each for its own reason and its own
message.  The report file is written unconditionally so the PR-comment step has
something to post either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

abi3 vs. version-specific build

Minimum of interleaved rounds. Regression threshold 1.25x (benchmarks under 5 ms are reported but never fail the job -- CI runners cannot resolve them).

macos-latest-3.11

Python 3.11.9, blosc2 4.11.0.dev0, numpy 2.4.6 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 338.133 ms 333.333 ms 0.986x
decompress2 8KB x5000 292.114 ms 281.554 ms 0.964x
SChunk attr access x600k 54.768 ms 58.364 ms 1.066x
SChunk decompress_chunk x64 0.580 ms 0.581 ms 1.002x
NDArray scalar getitem x5000 96.076 ms 96.987 ms 1.009x
NDArray full slice (control) 0.891 ms 0.623 ms 0.699x
NDArray row slice x1000 20.917 ms 19.154 ms 0.916x
lazyexpr a**2+b*2 (4M f64) 130.682 ms 130.225 ms 0.996x
where(a>0.5,a,b) (4M f64) 39.523 ms 38.996 ms 0.987x
sum(a+b) (4M f64) 9.441 ms 9.553 ms 1.012x
compress2 64MB (control) 13.812 ms 13.179 ms 0.954x
CTable utf8 ingest 200k rows 39.548 ms 40.190 ms 1.016x
CTable group_by+agg 200k 22.855 ms 23.370 ms 1.023x
CTable group_by 2 keys 200k 26.153 ms 25.898 ms 0.990x
CTable where() 200k 0.948 ms 0.949 ms 1.001x

macos-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 376.744 ms 371.639 ms 0.986x
decompress2 8KB x5000 299.881 ms 365.299 ms 1.218x
SChunk attr access x600k 29.067 ms 30.236 ms 1.040x
SChunk decompress_chunk x64 0.654 ms 0.634 ms 0.969x
NDArray scalar getitem x5000 131.432 ms 140.850 ms 1.072x
NDArray full slice (control) 0.364 ms 0.540 ms 1.480x ⚠️
NDArray row slice x1000 24.122 ms 22.675 ms 0.940x
lazyexpr a**2+b*2 (4M f64) 136.019 ms 161.969 ms 1.191x
where(a>0.5,a,b) (4M f64) 37.771 ms 48.619 ms 1.287x ❌
sum(a+b) (4M f64) 9.178 ms 10.698 ms 1.166x
compress2 64MB (control) 15.160 ms 14.820 ms 0.978x
CTable utf8 ingest 200k rows 48.859 ms 52.452 ms 1.074x
CTable group_by+agg 200k 22.409 ms 23.423 ms 1.045x
CTable group_by 2 keys 200k 24.413 ms 27.334 ms 1.120x
CTable where() 200k 1.111 ms 1.397 ms 1.258x ⚠️

ubuntu-latest-3.11

Python 3.11.15, blosc2 4.11.0.dev0, numpy 2.4.6 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 984.490 ms 1005.591 ms 1.021x
decompress2 8KB x5000 821.317 ms 826.545 ms 1.006x
SChunk attr access x600k 75.856 ms 75.374 ms 0.994x
SChunk decompress_chunk x64 1.204 ms 1.216 ms 1.010x
NDArray scalar getitem x5000 182.771 ms 183.836 ms 1.006x
NDArray full slice (control) 0.450 ms 0.464 ms 1.030x
NDArray row slice x1000 36.792 ms 36.895 ms 1.003x
lazyexpr a**2+b*2 (4M f64) 122.838 ms 121.934 ms 0.993x
where(a>0.5,a,b) (4M f64) 42.703 ms 42.843 ms 1.003x
sum(a+b) (4M f64) 10.407 ms 10.462 ms 1.005x
compress2 64MB (control) 17.004 ms 17.761 ms 1.045x
CTable utf8 ingest 200k rows 60.412 ms 59.924 ms 0.992x
CTable group_by+agg 200k 21.390 ms 21.531 ms 1.007x
CTable group_by 2 keys 200k 22.320 ms 22.241 ms 0.996x
CTable where() 200k 2.063 ms 2.015 ms 0.977x

ubuntu-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 1083.848 ms 1103.155 ms 1.018x
decompress2 8KB x5000 937.164 ms 941.436 ms 1.005x
SChunk attr access x600k 44.403 ms 44.487 ms 1.002x
SChunk decompress_chunk x64 1.186 ms 1.194 ms 1.007x
NDArray scalar getitem x5000 234.703 ms 243.374 ms 1.037x
NDArray full slice (control) 0.536 ms 0.574 ms 1.072x
NDArray row slice x1000 44.997 ms 46.486 ms 1.033x
lazyexpr a**2+b*2 (4M f64) 181.322 ms 181.154 ms 0.999x
where(a>0.5,a,b) (4M f64) 61.568 ms 62.130 ms 1.009x
sum(a+b) (4M f64) 12.076 ms 12.049 ms 0.998x
compress2 64MB (control) 16.707 ms 16.705 ms 1.000x
CTable utf8 ingest 200k rows 65.133 ms 64.152 ms 0.985x
CTable group_by+agg 200k 21.648 ms 22.035 ms 1.018x
CTable group_by 2 keys 200k 23.544 ms 23.362 ms 0.992x
CTable where() 200k 2.148 ms 2.167 ms 1.009x

windows-latest-3.11

Python 3.11.9, blosc2 4.11.0.dev0, numpy 2.4.6 — module D:\a\python-blosc2\python-blosc2\venv-abi3\Lib\site-packages\blosc2\blosc2_ext.pyd

benchmark base abi3 ratio
compress2 8KB x5000 2682.133 ms 2706.597 ms 1.009x
decompress2 8KB x5000 2273.937 ms 2283.396 ms 1.004x
SChunk attr access x600k 79.986 ms 79.747 ms 0.997x
SChunk decompress_chunk x64 1.757 ms 1.765 ms 1.005x
NDArray scalar getitem x5000 161.667 ms 164.868 ms 1.020x
NDArray full slice (control) 2.176 ms 2.201 ms 1.012x
NDArray row slice x1000 31.963 ms 32.312 ms 1.011x
lazyexpr a**2+b*2 (4M f64) 159.542 ms 159.833 ms 1.002x
where(a>0.5,a,b) (4M f64) 104.606 ms 105.921 ms 1.013x
sum(a+b) (4M f64) 48.467 ms 48.536 ms 1.001x
compress2 64MB (control) 18.593 ms 18.797 ms 1.011x
CTable utf8 ingest 200k rows 86.011 ms 85.785 ms 0.997x
CTable group_by+agg 200k 45.521 ms 46.202 ms 1.015x
CTable group_by 2 keys 200k 47.219 ms 48.615 ms 1.030x
CTable where() 200k 5.409 ms 5.354 ms 0.990x

windows-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module D:\a\python-blosc2\python-blosc2\venv-abi3\Lib\site-packages\blosc2\blosc2_ext.pyd

benchmark base abi3 ratio
compress2 8KB x5000 3391.884 ms 3385.674 ms 0.998x
decompress2 8KB x5000 3011.733 ms 3001.924 ms 0.997x
SChunk attr access x600k 53.859 ms 53.468 ms 0.993x
SChunk decompress_chunk x64 1.634 ms 1.661 ms 1.017x
NDArray scalar getitem x5000 216.758 ms 216.607 ms 0.999x
NDArray full slice (control) 2.024 ms 1.880 ms 0.929x
NDArray row slice x1000 40.096 ms 40.909 ms 1.020x
lazyexpr a**2+b*2 (4M f64) 164.752 ms 159.754 ms 0.970x
where(a>0.5,a,b) (4M f64) 114.398 ms 111.048 ms 0.971x
sum(a+b) (4M f64) 54.913 ms 55.419 ms 1.009x
compress2 64MB (control) 18.423 ms 17.357 ms 0.942x
CTable utf8 ingest 200k rows 83.613 ms 84.392 ms 1.009x
CTable group_by+agg 200k 42.335 ms 42.193 ms 0.997x
CTable group_by 2 keys 200k 44.468 ms 44.248 ms 0.995x
CTable where() 200k 5.721 ms 5.741 ms 1.003x

Worst non-noise ratio: 1.287x (where(a>0.5,a,b) (4M f64) on macos-latest-3.14)

1 benchmark(s) past threshold:

  • macos-latest-3.14 — where(a>0.5,a,b) (4M f64): 1.287x

At three rounds one cell (macos-latest / 3.14) flagged where() at 1.287x along
with the other large-array compute benchmarks, while the call-overhead-bound
benchmarks on that same cell -- compress2 of 8 KB buffers at 0.986x, SChunk
attribute access at 1.040x -- were clean.  That is backwards: abi3 taxes the
Python/C boundary, so a cost has to appear on the call-heavy benchmarks before
it appears on 4M-element vectorized compute.  The same where() benchmark came
in at 0.987x, 1.009x and 0.971x on the other three cells, and 0.969x locally.

So this is a noisy shared runner, not an ABI effect.  Five rounds gives the
per-benchmark minimum a larger sample to draw an uncontaminated observation
from, which is the point of using min as the estimator.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

abi3 vs. version-specific build

Minimum of interleaved rounds. Regression threshold 1.25x (benchmarks under 5 ms are reported but never fail the job -- CI runners cannot resolve them).

macos-latest-3.11

Python 3.11.9, blosc2 4.11.0.dev0, numpy 2.4.6 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 448.415 ms 323.792 ms 0.722x
decompress2 8KB x5000 253.189 ms 280.586 ms 1.108x
SChunk attr access x600k 51.433 ms 56.430 ms 1.097x
SChunk decompress_chunk x64 0.628 ms 0.625 ms 0.996x
NDArray scalar getitem x5000 105.449 ms 101.421 ms 0.962x
NDArray full slice (control) 1.151 ms 0.845 ms 0.735x
NDArray row slice x1000 21.083 ms 20.818 ms 0.987x
lazyexpr a**2+b*2 (4M f64) 142.322 ms 139.110 ms 0.977x
where(a>0.5,a,b) (4M f64) 40.398 ms 41.608 ms 1.030x
sum(a+b) (4M f64) 10.153 ms 10.847 ms 1.068x
compress2 64MB (control) 14.478 ms 16.301 ms 1.126x
CTable utf8 ingest 200k rows 40.500 ms 49.611 ms 1.225x
CTable group_by+agg 200k 23.301 ms 27.949 ms 1.199x
CTable group_by 2 keys 200k 25.898 ms 30.595 ms 1.181x
CTable where() 200k 1.048 ms 1.125 ms 1.073x

macos-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 547.991 ms 600.546 ms 1.096x
decompress2 8KB x5000 419.111 ms 424.638 ms 1.013x
SChunk attr access x600k 31.246 ms 28.990 ms 0.928x
SChunk decompress_chunk x64 0.625 ms 0.634 ms 1.015x
NDArray scalar getitem x5000 118.602 ms 133.493 ms 1.126x
NDArray full slice (control) 0.385 ms 0.581 ms 1.510x ⚠️
NDArray row slice x1000 21.837 ms 23.056 ms 1.056x
lazyexpr a**2+b*2 (4M f64) 165.017 ms 160.588 ms 0.973x
where(a>0.5,a,b) (4M f64) 46.115 ms 47.126 ms 1.022x
sum(a+b) (4M f64) 8.956 ms 8.987 ms 1.003x
compress2 64MB (control) 17.406 ms 16.104 ms 0.925x
CTable utf8 ingest 200k rows 56.833 ms 64.408 ms 1.133x
CTable group_by+agg 200k 24.652 ms 26.560 ms 1.077x
CTable group_by 2 keys 200k 28.982 ms 30.323 ms 1.046x
CTable where() 200k 0.993 ms 0.997 ms 1.004x

ubuntu-latest-3.11

Python 3.11.15, blosc2 4.11.0.dev0, numpy 2.4.6 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 1078.837 ms 1100.220 ms 1.020x
decompress2 8KB x5000 916.237 ms 921.520 ms 1.006x
SChunk attr access x600k 75.371 ms 73.521 ms 0.975x
SChunk decompress_chunk x64 1.188 ms 1.200 ms 1.010x
NDArray scalar getitem x5000 215.863 ms 217.603 ms 1.008x
NDArray full slice (control) 0.561 ms 0.548 ms 0.978x
NDArray row slice x1000 43.340 ms 44.011 ms 1.015x
lazyexpr a**2+b*2 (4M f64) 181.302 ms 180.843 ms 0.997x
where(a>0.5,a,b) (4M f64) 61.330 ms 61.629 ms 1.005x
sum(a+b) (4M f64) 11.812 ms 11.900 ms 1.007x
compress2 64MB (control) 16.505 ms 17.744 ms 1.075x
CTable utf8 ingest 200k rows 57.989 ms 58.994 ms 1.017x
CTable group_by+agg 200k 20.888 ms 20.908 ms 1.001x
CTable group_by 2 keys 200k 22.318 ms 22.410 ms 1.004x
CTable where() 200k 2.127 ms 2.025 ms 0.952x

ubuntu-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module blosc2_ext.abi3.so

benchmark base abi3 ratio
compress2 8KB x5000 781.644 ms 792.645 ms 1.014x
decompress2 8KB x5000 672.981 ms 682.257 ms 1.014x
SChunk attr access x600k 34.924 ms 35.267 ms 1.010x
SChunk decompress_chunk x64 0.926 ms 0.939 ms 1.014x
NDArray scalar getitem x5000 149.676 ms 150.553 ms 1.006x
NDArray full slice (control) 0.367 ms 0.368 ms 1.001x
NDArray row slice x1000 29.043 ms 29.135 ms 1.003x
lazyexpr a**2+b*2 (4M f64) 94.639 ms 94.710 ms 1.001x
where(a>0.5,a,b) (4M f64) 32.972 ms 33.318 ms 1.011x
sum(a+b) (4M f64) 8.098 ms 8.071 ms 0.997x
compress2 64MB (control) 12.949 ms 13.010 ms 1.005x
CTable utf8 ingest 200k rows 50.836 ms 50.494 ms 0.993x
CTable group_by+agg 200k 24.043 ms 24.266 ms 1.009x
CTable group_by 2 keys 200k 30.740 ms 30.984 ms 1.008x
CTable where() 200k 1.583 ms 1.603 ms 1.013x

windows-latest-3.11

Python 3.11.9, blosc2 4.11.0.dev0, numpy 2.4.6 — module D:\a\python-blosc2\python-blosc2\venv-abi3\Lib\site-packages\blosc2\blosc2_ext.pyd

benchmark base abi3 ratio
compress2 8KB x5000 3136.022 ms 3127.031 ms 0.997x
decompress2 8KB x5000 2738.606 ms 2716.332 ms 0.992x
SChunk attr access x600k 80.806 ms 79.647 ms 0.986x
SChunk decompress_chunk x64 1.648 ms 1.650 ms 1.001x
NDArray scalar getitem x5000 204.405 ms 212.290 ms 1.039x
NDArray full slice (control) 1.913 ms 1.982 ms 1.036x
NDArray row slice x1000 39.660 ms 41.790 ms 1.054x
lazyexpr a**2+b*2 (4M f64) 161.265 ms 160.375 ms 0.994x
where(a>0.5,a,b) (4M f64) 111.794 ms 112.596 ms 1.007x
sum(a+b) (4M f64) 54.897 ms 54.954 ms 1.001x
compress2 64MB (control) 17.131 ms 17.470 ms 1.020x
CTable utf8 ingest 200k rows 83.103 ms 85.257 ms 1.026x
CTable group_by+agg 200k 44.055 ms 44.444 ms 1.009x
CTable group_by 2 keys 200k 46.559 ms 46.921 ms 1.008x
CTable where() 200k 5.787 ms 5.772 ms 0.997x

windows-latest-3.14

Python 3.14.6, blosc2 4.11.0.dev0, numpy 2.5.2 — module D:\a\python-blosc2\python-blosc2\venv-abi3\Lib\site-packages\blosc2\blosc2_ext.pyd

benchmark base abi3 ratio
compress2 8KB x5000 3248.596 ms 3267.012 ms 1.006x
decompress2 8KB x5000 2868.706 ms 2880.157 ms 1.004x
SChunk attr access x600k 53.383 ms 53.005 ms 0.993x
SChunk decompress_chunk x64 1.632 ms 1.648 ms 1.009x
NDArray scalar getitem x5000 214.676 ms 220.838 ms 1.029x
NDArray full slice (control) 2.094 ms 2.094 ms 1.000x
NDArray row slice x1000 40.312 ms 41.569 ms 1.031x
lazyexpr a**2+b*2 (4M f64) 159.809 ms 159.549 ms 0.998x
where(a>0.5,a,b) (4M f64) 110.345 ms 110.613 ms 1.002x
sum(a+b) (4M f64) 54.832 ms 54.719 ms 0.998x
compress2 64MB (control) 17.937 ms 17.363 ms 0.968x
CTable utf8 ingest 200k rows 84.552 ms 83.956 ms 0.993x
CTable group_by+agg 200k 43.045 ms 42.241 ms 0.981x
CTable group_by 2 keys 200k 45.639 ms 45.161 ms 0.990x
CTable where() 200k 5.678 ms 5.708 ms 1.005x

Worst non-noise ratio: 1.225x (CTable utf8 ingest 200k rows on macos-latest-3.11)

No regression past threshold on any platform. ✅

It has done its job.  Across six platform/version cells the abi3 build showed
no cost: worst ratio 1.075x on Linux and 1.054x on Windows over every
benchmark.  Both specific worries came back negative -- Windows, where an abi3
extension calls through the python3.dll forwarder, was the cleanest platform in
the matrix, and 3.11 running a binary compiled to the 3.11 Limited API showed
nothing.

The macOS runners turned out to resolve no better than about +/-25% (the same
benchmark swung 1.287x on one run and 1.022x on the next, and another posted a
0.722x "speedup"), so the Linux and Windows cells carry the evidence.  An
outlier that relocates between runs is noise; a real ABI cost would land on the
call-heavy benchmarks first and stay put.

Not kept as a permanent job: it doubles every wheel build to produce a
comparison, and the platform where it would matter -- manylinux aarch64 --
is the one it never covered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@FrancescAlted

Copy link
Copy Markdown
Member Author

This seems goo to go. The worse slowdown is NDArray full slice (control) (0.364 ms vs 0.540 ms for ~1.5x), but this cannot be reproduced locally, and timings are typically around just 5% in performance so this has been a clear outlier. This makes sense, as most of bottlenecks are in compressing/decompressing, and in I/O (be memory, disk or the network).

At any rate, reducing the number of wheels seems a good thing, so merging.

@FrancescAlted
FrancescAlted merged commit d28e022 into main Aug 11, 2026
36 of 37 checks passed
@FrancescAlted
FrancescAlted deleted the abi3 branch August 11, 2026 13:02
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