Repository navigation
Optimize array_diff() for long values - #22648
mehmetcansahin wants to merge 2 commits into
Conversation
abc4fc9 to
9e1e3c1
Compare
9e1e3c1 to
b5a4a7f
Compare
|
I measured this on master c65321c (b5a4a7f merges with a conflict in Change in CPU cycles per call with the PR, relative to master (negative = fewer cycles, faster); median of five alternating runs:
Ints that fit the bitset take 71–88% fewer cycles; the example from the description takes 7.9–8.2× fewer, as reported. Calls that do not take the bitset path pay for the check first. When the first value is not an int, the call to I tried two changes on top of the PR (diffs): checking the type of the first value of the first array inline in
Correctness: the result with its keys, references and refcounts ( Tests: every case in No correctness issues found. Before this is merged, could you look at the cost for calls that fall back, at least the inline first-value check? I can send either change as a PR to your branch. Full tables, scripts and data: https://github.com/ArtUkrainskiy/php-src-bench/tree/main/reports/pr-22648-array-diff |
Check the first value's type inline before calling php_array_diff_long(), and scan the exclude arrays before the first array so sparse or non-int exclusions fall back without a full scan of the first array. Allocate the bitset with ZEND_BITSET_ALLOCA like the other bitsets in this file. Add a test building a bitset of more than one word, a NEWS entry, and clarify that only the values to exclude need to be dense. Suggested by @ArtUkrainskiy.
b5a4a7f to
e104be4
Compare
|
Thanks! Rebased and pushed both variants, a multi-word bitset test, |
array_diff()currently builds its exclusion set from string representations, causing avoidable conversions for large integer-only inputs. This adds a collision-safe fast path using a bitset for compact integer ranges; mixed or sparse inputs continue through the existing path.Result: ~0.12s before, ~0.015s after (approximately 8x faster). Unlike the earlier integer-keyed
HashTableapproach, this retains linear worst-case behavior.Tests cover integer limits, duplicates, key and reference preservation, and fallback behavior.