Skip to content

Commit 4ad8a01

Browse files
committed
Add more benchmarks from separate perf work branch
1 parent 5577ff1 commit 4ad8a01

1 file changed

Lines changed: 138 additions & 1 deletion

File tree

Tests/benchmarks.py

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import pytest
1111

12-
from PIL import Image, ImageFilter
12+
from PIL import Image, ImageChops, ImageFilter
1313
from PIL.Image import Resampling, Transpose
1414

1515
TYPE_CHECKING = False
@@ -341,3 +341,140 @@ def test_merge(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> Non
341341
bands = im.split()
342342
bench.extra_info["label"] = [f"merge {mode}"]
343343
bench(Image.merge, mode, bands)
344+
345+
346+
@pytest.mark.benchmark(group="allocate")
347+
@pytest.mark.parametrize("mode", MODES)
348+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
349+
def test_fill(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
350+
nbands = len(Image.new(mode, (1, 1)).getbands())
351+
color = (10, 20, 30, 40)[:nbands] if nbands > 1 else 10
352+
bench.extra_info["label"] = [f"fill {mode}"]
353+
bench(Image.new, mode, size, color)
354+
355+
356+
CHOPS_OPS = [
357+
ImageChops.add,
358+
ImageChops.subtract,
359+
ImageChops.multiply,
360+
ImageChops.screen,
361+
ImageChops.difference,
362+
ImageChops.lighter,
363+
ImageChops.darker,
364+
ImageChops.add_modulo,
365+
ImageChops.soft_light,
366+
ImageChops.hard_light,
367+
ImageChops.overlay,
368+
]
369+
370+
371+
@pytest.mark.benchmark(group="chops")
372+
@pytest.mark.parametrize("op", CHOPS_OPS, ids=lambda f: f.__name__)
373+
@pytest.mark.parametrize("mode", MODES)
374+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
375+
def test_chops(
376+
bench: BenchmarkFixture,
377+
mode: str,
378+
size: tuple[int, int],
379+
op: str,
380+
) -> None:
381+
im1 = make_pillow_image(mode, size)
382+
im2 = make_pillow_image(mode, size, pattern_offset=1024)
383+
bench.extra_info["label"] = [op.__name__]
384+
result = bench(op, im1, im2)
385+
assert result.size == im1.size
386+
387+
388+
@pytest.mark.benchmark(group="chops")
389+
@pytest.mark.parametrize("mode", MODES)
390+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
391+
def test_invert(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
392+
im = make_pillow_image(mode, size)
393+
bench.extra_info["label"] = ["invert"]
394+
bench(ImageChops.invert, im)
395+
396+
397+
@pytest.mark.benchmark(group="chops")
398+
@pytest.mark.parametrize("mode", MODES)
399+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
400+
def test_offset(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
401+
im = make_pillow_image(mode, size)
402+
bench.extra_info["label"] = ["offset"]
403+
bench(ImageChops.offset, im, 123, 45)
404+
405+
406+
@pytest.mark.benchmark(group="histogram")
407+
@pytest.mark.parametrize("mode", MODES)
408+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
409+
def test_histogram(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
410+
im = make_pillow_image(mode, size)
411+
bench.extra_info["label"] = [f"histogram {mode}"]
412+
bench(im.histogram)
413+
414+
415+
@pytest.mark.benchmark(group="histogram")
416+
@pytest.mark.parametrize("mode", MODES)
417+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
418+
def test_histogram_masked(
419+
bench: BenchmarkFixture, mode: str, size: tuple[int, int]
420+
) -> None:
421+
im = make_pillow_image(mode, size)
422+
mask = make_pillow_image("L", size)
423+
bench.extra_info["label"] = [f"masked histogram {mode}"]
424+
bench(im.histogram, mask)
425+
426+
427+
L_MATRIX = (0.299, 0.587, 0.114, 0.0)
428+
RGB_MATRIX = (
429+
0.412, 0.357, 0.180, 0.0,
430+
0.212, 0.715, 0.072, 0.0,
431+
0.019, 0.119, 0.950, 0.0,
432+
) # fmt: skip
433+
434+
435+
@pytest.mark.benchmark(group="convert")
436+
@pytest.mark.parametrize(
437+
"mode_to, matrix",
438+
[("L", L_MATRIX), ("RGB", RGB_MATRIX)],
439+
)
440+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
441+
def test_matrix_convert(
442+
bench: BenchmarkFixture,
443+
mode_to: str,
444+
matrix: tuple[float, ...],
445+
size: tuple[int, int],
446+
) -> None:
447+
im = make_pillow_image("RGB", size)
448+
bench.extra_info["label"] = [f"matrix RGB to {mode_to}"]
449+
bench(im.convert, mode_to, matrix)
450+
451+
452+
@pytest.mark.benchmark(group="point")
453+
@pytest.mark.parametrize("mode", MODES)
454+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
455+
def test_point_lut(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
456+
im = make_pillow_image(mode, size)
457+
lut = [255 - i for i in range(256)] * len(im.getbands())
458+
bench.extra_info["label"] = [f"LUT {mode}"]
459+
bench(im.point, lut)
460+
461+
462+
@pytest.mark.benchmark(group="point")
463+
@pytest.mark.parametrize("mode", ["I", "F"])
464+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
465+
def test_point_transform(
466+
bench: BenchmarkFixture, mode: str, size: tuple[int, int]
467+
) -> None:
468+
im = make_pillow_image(mode, size)
469+
bench.extra_info["label"] = [f"transform {mode}"]
470+
bench(im.point, lambda v: v * 1.5 + 3.0)
471+
472+
473+
@pytest.mark.benchmark(group="quantize")
474+
@pytest.mark.parametrize("mode", [m for m in MODES if m in ("L", "RGB", "RGBA")])
475+
@pytest.mark.parametrize("size", SIZES, ids=_format_size)
476+
def test_quantize(bench: BenchmarkFixture, mode: str, size: tuple[int, int]) -> None:
477+
im = make_pillow_image(mode, size)
478+
bench.extra_info["label"] = [f"quantize {mode}"]
479+
result = bench(im.quantize, 256)
480+
assert result.mode == "P"

0 commit comments

Comments
 (0)