Repository navigation
sort()/rsort(): exact zend_sort + native zend_compare + int radix path (O(n²) → faster than Zend) - #37725
Merged
Conversation
… int radix path
sort()/rsort() (SORT_REGULAR, SORT_STRING|SORT_FLAG_CASE) were a bubble sort
— O(n²), sorting 1.5M ints never finished — comparing strings with plain
strcmp (SORT_REGULAR compares numeric strings numerically) and mixed types
through a spaceship runtime that ranks every int below every string.
- ZendSortLlvm: php-src Zend/zend_sort.c (8.2) reproduced exactly —
zend_insert_sort (networks for 2..5, guarded insertion with 2-step probe)
and the median-of-3/5 hybrid quicksort, recursion as an explicit
smaller-part-first stack — over an index permutation, plus
RETURN_STABLE_SORT's tiebreak on original position. Same algorithm =>
same output for non-transitive mixed comparisons and the same comparator
call sequence. Comparator is its own internal function (a shared
comparator block with a continuation switch crashed LLVM 9's RA).
- ZendCompareLlvm (__phpc_zend_compare): zend_compare for every pair of
null/bool/int/float/string — compare_long_to_string,
compare_double_to_string, zendi_smart_strcmp with php-src's overflow
rules, ZEND_NORMALIZE_BOOL NaN behaviour; arrays/objects keep the old
runtime.
- NumericStringLlvm: php-src's first-byte fast reject; NUMERIC_OFLOW_POS/
NEG statuses (is_numeric_string's oflow) for smart_strcmp.
- Fast paths where zend_compare is a consistent total order, so any
correct stable sort equals zend_sort's result exactly:
all ints -> LSD radix sort (IntRadixSortLlvm, O(n), no comparator calls);
all non-numeric strings -> stable merge sort (MergeSortLlvm) over
contiguous {big-endian 8-byte prefix, index} keys, memcmp only on ties.
Lab timings (1.5M elements incl. array build, Zend 8.2 pinned image, best of
3, output identical): ints 0.147s vs Zend 0.283s; non-numeric strings 0.49s
vs 0.50s; benchmarks/v2 sort-mixed scaled 0.51s vs 0.69s (was: no result).
New differential cases (Zend oracle): sort_zend_parity (ints, strings,
numeric strings, 40-element non-transitive mixed arrays, sort/rsort, flag
case), pow_int_overflow_parity, numeric_string_arith_parity,
operand_typeerror_runtime_names — from the previous commits' work.
Gates: make check OK; parallel AOT differential sweep (386 cases, 3 runs):
374 ok / 8 fail, identical failing set to current master; sort_zend_parity
20/20 runs identical (an uninitialized parse box caused intermittent
corruption during development — scratch boxes are now IS_NULL-initialized).
Not converted yet: usort/uasort/uksort, asort/arsort, ksort/krsort,
array_multisort still bubble-sort (next).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See commit message for details. Gates:
make checkOK; parallel AOT differential sweep (386 cases ×3 runs) identical failing set to master (374 ok / 8 fail); new Zend-oracle cases added. Not run: compliance suites.🤖 Generated with Claude Code