Skip to content

Avoid sorting and filtering in hot lookups - #1541

Merged
olivervogel merged 1 commit into
Intervention:developfrom
silarhi:feature/linear-color-channel-and-polygon-lookups
Oct 3, 2026
Merged

olivervogel merged 1 commit into
Intervention:developfrom
silarhi:feature/linear-color-channel-and-polygon-lookups

Conversation

@guillaume-sainthillier

Copy link
Copy Markdown
Contributor

AbstractColor::channel() ran array_filter() with a closure on every lookup, which happens many times per modifier (~120 times for 10 modifiers on a small image). Polygon::most*Point() sorted all points to read a single one.

Now a loop returning the first match and linear scans, which keep the same results, including ties (usort() is stable). Both showed up in profiles of small images (~13% of a pass of 10 modifiers).

AbstractColor::channel() ran array_filter() with a closure on every
channel lookup, which happens many times per modifier (e.g. ~120 times
for 10 modifiers on a small image). Polygon::most*Point() sorted all
points to read a single extreme point.

Use a plain loop returning the first match and linear scans instead,
which keep the same results including ties, as usort() is stable.

@deluxetom deluxetom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Reviewed at 2c4d57e. The results are the same, including ties: for 20,000 random polygons with many equal coordinates, all four most*Point() methods return the same point index as develop. channel() returns the same channel and throws the same exception for a missing channel. The empty-polygon behavior has not changed. Local timing: channel() 243 -> 65 ns, mostLeftPoint() 510 -> 155 ns. Full suite passes in the project Docker image (IM 7.1.2 and 6.9.13). Locally the only failures are the pre-existing JP2/HEIC delegate failures, the same as on develop. PHPStan and PHPCS are clean. CI for this PR has not run yet (workflow awaits approval).

@olivervogel

Copy link
Copy Markdown
Member

Thanks.

@olivervogel
olivervogel merged commit 1508a5b into Intervention:develop Oct 3, 2026
8 checks passed
olivervogel pushed a commit that referenced this pull request Oct 4, 2026
AbstractColor::channel() ran array_filter() with a closure on every
channel lookup, which happens many times per modifier (e.g. ~120 times
for 10 modifiers on a small image). Polygon::most*Point() sorted all
points to read a single extreme point.

Use a plain loop returning the first match and linear scans instead,
which keep the same results including ties, as usort() is stable.
@guillaume-sainthillier
guillaume-sainthillier deleted the feature/linear-color-channel-and-polygon-lookups branch October 5, 2026 07:36
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.

3 participants