Skip to content

Test speedups - #10042

Open
akx wants to merge 5 commits into
python-pillow:mainfrom
akx:test-speedups
Open

akx wants to merge 5 commits into
python-pillow:mainfrom
akx:test-speedups

Conversation

@akx

@akx akx commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

On my machine, this speeds up the entire test suite by ~8% on average, when running on all cores. (hyperfine)

~/b/Pillow (main) $ uv pip install -e . && hyperfine 'uv run -m pytest -nlogical --dist=worksteal'
Benchmark 1: uv run -m pytest -nlogical --dist=worksteal
  Time (mean ± σ):     11.237 s ±  0.323 s    [User: 61.079 s, System: 10.519 s]
  Range (min … max):   10.719 s … 11.919 s    10 runs

~/b/Pillow (test-speedups) $ uv pip install -e . && hyperfine 'uv run -m pytest -nlogical --dist=worksteal'
Benchmark 1: uv run -m pytest -nlogical --dist=worksteal
  Time (mean ± σ):     10.419 s ±  0.424 s    [User: 58.852 s, System: 10.216 s]
  Range (min … max):   10.048 s … 11.393 s    10 runs
  • test_apng_save_split_fdat was spending time compressing data, but the premise of the test is to see whether large data is split across chunks correctly. The test now uses smaller data and a small MAXCHUNK, and tests the premise.
  • Not a speedup, but 29ff5fc had replaced some patching with proper pytest monkeypatching, but left some stray globals in the files. Those get cleaned up.
  • test_parser() is split up with parametrization (or in the explicitly failing case of PDFs, into a separate test...), so the different formats run in parallel (Run tests in parallel with pytest-xdist #9945 and all that).
  • convert_to_comparable used get_flattened_data to convert a palette image to a list of numbers, just so it could be again interpreted as L bytes. Can just as well go with the bytes themselves (and Improve memory usage and performance for tobytes() #9938 will speed that up too).
  • assert_image_similar now uses ImageChops.difference() to compute the difference map between 8bpp images in one multiband sweep. (This got faster in Speed up ImageChops operations #9738.) (ImageChops functions don't do non-8bpp at all; I might take a look at that.) Since many of the tests end up doing assert_image_similar, that's a nice win. (Improve memory usage and performance for tobytes() #9938 will speed up assert_image_equal.) This is probably the source of most of the speedup here. :)

@akx

akx commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

The reason I started looking at assert_image_similar was this tracy-via-tracypy fragment:

Screenshot 2026-09-22 at 18 02 14

@akx

This comment was marked as outdated.

Comment thread Tests/test_file_apng.py
default_image=True,
append_images=frames,
)
assert test_file.read_bytes().count(b"fdAT") > 2

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we have a difference of opinion on this, but I still don't see minor performance improvements in the test suite as a reason to start monkeypatching. I would rather test Pillow as it is with a real image.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pillow is not being monkeypatched. MAXBLOCK is a documented public API, this just sets it temporarily.

This is the same pattern as used in e.g. test_padded_idat in test_file_png.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants