[php-src] PR #25280: ext/standard: Speed up strict in_array()/array_search() with a string needle
| From: | adapik | Date: | Sat, 07 Nov 2026 11:33:22 +0000 |
| Subject: | [php-src] PR #25280: ext/standard: Speed up strict in_array()/array_search() with a string needle | ||
| Groups: | php.git-pulls | ||
| Request: | Send a blank email to git-pulls+get-40387@lists.php.net to get a copy of this message | ||
Pull Request: https://github.com/php/php-src/pull/25280
Author: adapik
In 107ae86ca6b specialized comparisons were added to in_array() for integer and string needles, to
avoid repeating the type checks on every iteration. That covered loose mode only. Strict mode kept
going through the generic identity check for every element.
Later @nikic noticed the gap for integers: it doesn't make sense that strict=false is much
faster than strict just for lack of a specialized codepath, and added an integer loop for strict
mode (ea86a9209c0). Strings were not touched, so strict mode with a string needle still calls
zend_is_identical() for every element.
The result is that the same gap is still there for strings. On master in_array($str, $list, true) is
about 2x slower than the loose version when the needle isn't found (1.7x in instructions, 2.0x
in time).
This PR adds the missing loop, next to the integer one. After it, strict and loose are on par for
string needles (about 21 vs 23 instructions per element).
Instructions per call, array of N strings (callgrind, release build):
- N=5: -15% if found, -27% if not found
- N=50: -23% / -45%
- N=500: -23% / -48%
- N=5000: -23% / -49%
At N=500 the time goes from 95 to 62 ms (found) and from 79 to 40 ms (not found). Other needle types
are unchanged, except null, which costs 3 more instructions per call.