Skip to content

Conversation

@hugovk
Copy link
Member

@hugovk hugovk commented Dec 26, 2023

Use functools.lru_cache instead of our own global cache, to only cache those which are requested.

With no argument, lru_cache defaults to maxsize=128, plenty for the 33 valid inputs.

https://docs.python.org/3/library/functools.html#functools.lru_cache

Performance improves for all the following cases.

A mode from the top half: 33.6 -> 28.5 nsec

Before and after:

python3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('RGB')"
10000000 loops, best of 5: 33.6 nsec per looppython3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('RGB')"
10000000 loops, best of 5: 28.5 nsec per loop

A mapping mode from the bottom half: 36 -> 28.9 nsec

python3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('I;16N')"
10000000 loops, best of 5: 36 nsec per looppython3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('I;16N')"
10000000 loops, best of 5: 28.9 nsec per loop

All modes: 1.25 -> 1.01 usec

python3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('1'); ImageMode.getmode('L'); ImageMode.getmode('I'); ImageMode.getmode('F'); ImageMode.getmode('P'); ImageMode.getmode('RGB'); ImageMode.getmode('RGBX'); ImageMode.getmode('RGBA'); ImageMode.getmode('CMYK'); ImageMode.getmode('YCbCr'); ImageMode.getmode('LAB'); ImageMode.getmode('HSV'); ImageMode.getmode('RGBa'); ImageMode.getmode('BGR;15'); ImageMode.getmode('BGR;16'); ImageMode.getmode('BGR;24'); ImageMode.getmode('LA'); ImageMode.getmode('La'); ImageMode.getmode('PA'); ImageMode.getmode('I;16'); ImageMode.getmode('I;16S'); ImageMode.getmode('I;16L'); ImageMode.getmode('I;16LS'); ImageMode.getmode('I;16B'); ImageMode.getmode('I;16BS'); ImageMode.getmode('I;16N'); ImageMode.getmode('I;16NS'); ImageMode.getmode('I;32'); ImageMode.getmode('I;32B'); ImageMode.getmode('I;32L'); ImageMode.getmode('I;32S'); ImageMode.getmode('I;32BS'); ImageMode.getmode('I;32LS')"
200000 loops, best of 5: 1.25 usec per looppython3 -m timeit -s "from PIL import ImageMode" "ImageMode.getmode('1'); ImageMode.getmode('L'); ImageMode.getmode('I'); ImageMode.getmode('F'); ImageMode.getmode('P'); ImageMode.getmode('RGB'); ImageMode.getmode('RGBX'); ImageMode.getmode('RGBA'); ImageMode.getmode('CMYK'); ImageMode.getmode('YCbCr'); ImageMode.getmode('LAB'); ImageMode.getmode('HSV'); ImageMode.getmode('RGBa'); ImageMode.getmode('BGR;15'); ImageMode.getmode('BGR;16'); ImageMode.getmode('BGR;24'); ImageMode.getmode('LA'); ImageMode.getmode('La'); ImageMode.getmode('PA'); ImageMode.getmode('I;16'); ImageMode.getmode('I;16S'); ImageMode.getmode('I;16L'); ImageMode.getmode('I;16LS'); ImageMode.getmode('I;16B'); ImageMode.getmode('I;16BS'); ImageMode.getmode('I;16N'); ImageMode.getmode('I;16NS'); ImageMode.getmode('I;32'); ImageMode.getmode('I;32B'); ImageMode.getmode('I;32L'); ImageMode.getmode('I;32S'); ImageMode.getmode('I;32BS'); ImageMode.getmode('I;32LS')"
200000 loops, best of 5: 1.01 usec per loop

Co-authored-by: Andrew Murray <[email protected]>
@radarhere radarhere merged commit 1e8bad8 into python-pillow:main Dec 26, 2023
@hugovk hugovk deleted the optimise-imagemode branch December 27, 2023 05:10
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.

2 participants