Skip to content

ext/standard: Optimize sort() and rsort() for packed arrays - #23585

Draft
LamentXU123 wants to merge 2 commits into
php:masterfrom
LamentXU123:opt-sort
Draft

ext/standard: Optimize sort() and rsort() for packed arrays#23585
LamentXU123 wants to merge 2 commits into
php:masterfrom
LamentXU123:opt-sort

Conversation

@LamentXU123

@LamentXU123 LamentXU123 commented Sep 5, 2026

Copy link
Copy Markdown
Member

After the last trivial one-element optimization I get to be familiar with how sort works in Zend. So, now, except the array is empty or only has one element, we convert arrays to mixed storage before sorting, and convert them back after we sort them.

The reason we are doing this is because the internal sorting functions is using Buckets, so we can preserve the keys when sorting the values. Packed arrays (most cases we are sorting them instead of unpacked and mixed arrays), are sequence zvals, and don't have customized keys.

This let me thinking. Can we just implement a sort internally which completely works with zvals and not Buckets? So we don't need to convert them to Bucket and convert them back again when sorting packed arrays that don't have external keys at all?

I have a idea to implement a sort works with integer arrays entirely depending on zvals. There it is. I set a threshold to use this new internal function instead of the original one when the array to be sorted is large (>= 64 elements), packed and contains fully int. This is because sort functions with fully int arrays is easy to implement (I don't need to consider user's fallback function etc.) and since we are now not doing creating new Buckets and destroying them the benefits mainly comes from larger arrays, both in the aspect of time and memory spaces.

I ran benchmarks on a 64-elements, fully int array. Also, somehow this is also way more faster when we are sorting on a already sorted array, which is like a bonus.

Benchmark:

Case Baseline batch Candidate batch Time change
Random integers, sort() 178.99 ms 149.92 ms -16.24%
Random integers, rsort() 235.23 ms 127.49 ms -45.80%
Already sorted integers, sort() 66.86 ms 30.15 ms -54.91%

And this is the results with a 1,000,000 element array FYI.

Case Baseline Candidate Time change
Random integers, sort() 355.47 ms 226.61 ms -36.25%
Random integers, rsort() 542.42 ms 187.24 ms -65.48%
Already sorted integers, sort() 162.24 ms 58.58 ms -63.89%

@LamentXU123 LamentXU123 changed the title ext/standard: Optimize sort() and rsort() for large packed integer arrays ext/standard: Optimize sort() and rsort() for packed integer arrays Sep 6, 2026
@staabm

staabm commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Nice to see faster sorting. In PHPStan profiles we see slow sorting in https://github.com/phpstan/phpstan-src/blob/2.3.x/src/Type/TypeCombinator.php in most profiles (which is not sorting on pure integers though)

@LamentXU123 LamentXU123 changed the title ext/standard: Optimize sort() and rsort() for packed integer arrays ext/standard: Optimize sort() and rsort() for large packed integer arrays Sep 6, 2026
@LamentXU123
LamentXU123 marked this pull request as draft September 6, 2026 16:32
@LamentXU123

Copy link
Copy Markdown
Member Author

TBH, I don't think this is a completed PR. The idea is good, but we can't just implement this only for integers. Ideally, we can implement a sort completely supporting any zvals to be used by packed arrays.

I will be working on that idea in the coming days. So this is now drafted, sorry to ping you so early. I will request reviews when I think the implementaion is done.

Feel free to comment about the idea itself :)

@LamentXU123 LamentXU123 changed the title ext/standard: Optimize sort() and rsort() for large packed integer arrays ext/standard: Optimize sort() and rsort() for packed arrays Sep 6, 2026
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