Skip to content

Speed up Image.fill(), Image.linear_gradient() and Image.radial_gradient().#9737

Merged
hugovk merged 4 commits into
python-pillow:mainfrom
akx:faster-fill
Jul 1, 2026
Merged

Speed up Image.fill(), Image.linear_gradient() and Image.radial_gradient().#9737
hugovk merged 4 commits into
python-pillow:mainfrom
akx:faster-fill

Conversation

@akx

@akx akx commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Refs #9649, #9675, #9736 (same series, same techniques).

I didn't even know about linear_gradient and radial_gradient before looking at this...

@codspeed-hq

codspeed-hq Bot commented Jun 30, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by ×2.1

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 3 improved benchmarks
✅ 328 untouched benchmarks
🆕 10 new benchmarks

Performance Changes

Benchmark BASE HEAD Efficiency
test_fill[1024x1024-RGBA] 4.6 ms 2.2 ms ×2.1
test_fill[1024x1024-LA] 4.6 ms 2.2 ms ×2.1
test_fill[1024x1024-RGB] 4.6 ms 2.2 ms ×2.1
🆕 test_linear_gradient[1] N/A 76.4 µs N/A
🆕 test_linear_gradient[F] N/A 175.8 µs N/A
🆕 test_linear_gradient[I] N/A 175.7 µs N/A
🆕 test_linear_gradient[L] N/A 72.8 µs N/A
🆕 test_linear_gradient[P] N/A 95.4 µs N/A
🆕 test_radial_gradient[1] N/A 402.1 µs N/A
🆕 test_radial_gradient[F] N/A 524.3 µs N/A
🆕 test_radial_gradient[I] N/A 487.3 µs N/A
🆕 test_radial_gradient[L] N/A 398.2 µs N/A
🆕 test_radial_gradient[P] N/A 419 µs N/A

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing akx:faster-fill (f7f350a) with main (6590b1b)

Open in CodSpeed

@akx

akx commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

My local results for the new benchmarks:

linear_gradient was already well-optimized (the generated assembly did the right thing) for 1/L/P/F in the baseline, hence no gains over measurement noise there.

  -------------------------- benchmark 'allocate': 10 tests, 2 sources --------------------------
  Name (time in us)           0003_basegra OPS (Kops/s)  0004_newgrad OPS (Kops/s)  ΔOPS (Kops/s)
  -----------------------------------------------------------------------------------------------
  test_linear_gradient[1]                      575.2680                   581.8250          +1.1%
  test_linear_gradient[L]                      576.4618                   569.9319          -1.1%
  test_linear_gradient[P]                      421.5023                   400.9303          -4.9%
  test_linear_gradient[F]                      195.4028                   203.2991          +4.0%
  test_linear_gradient[I]                       39.9882                   201.5319        +404.0%
  test_radial_gradient[F]                       26.4618                    26.8236          +1.4%
  test_radial_gradient[L]                       22.2012                    26.1221         +17.7%
  test_radial_gradient[1]                       22.9234                    25.6476         +11.9%
  test_radial_gradient[P]                       22.1137                    25.4123         +14.9%
  test_radial_gradient[I]                       19.9459                    25.6850         +28.8%
  -----------------------------------------------------------------------------------------------

@akx akx marked this pull request as ready for review June 30, 2026 07:54
Comment thread src/libImaging/Fill.c Outdated
@hugovk hugovk merged commit 53e02c4 into python-pillow:main Jul 1, 2026
55 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants