[php-src] PR #25115: zend_memnstr: Use a compact Sunday shift table for short needles

From: Date: Sat, 31 Oct 2026 22:06:16 +0000
Subject: [php-src] PR #25115: zend_memnstr: Use a compact Sunday shift table for short needles
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-40161@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/25115 Author: ArtUkrainskiy I use a 256-byte Sunday shift table for 9–31-byte needles. The compact path requires at least 1024 input bytes remaining. Every shift fits in one byte. The search loop and first-match behavior stay the same. Short inline searches and the wide-table algorithm remain unchanged. Measured on a Ryzen 9 5950X with GCC 15.2 and Clang 21.1. Each moderation row checks all 12 banlist entries without a match. These are generated application fixtures. Times are microseconds per complete PHP operation, after empty-loop subtraction. Negative deltas mean less time relative to master. | Product case, input bytes | GCC master | GCC compact | Time Δ | Clang master | Clang compact | Time Δ | |---|--:|--:|--:|--:|--:|--:| | English moderation post, 1081 B | 2.9496 | 2.6783 | -9.20% | 2.8060 | 2.5239 | -10.05% | | Russian moderation post, 1041 B | 3.0331 | 2.8469 | -6.14% | 2.8824 | 2.7330 | -5.19% | | Spanish moderation post, 1086 B | 2.8435 | 2.5977 | -8.65% | 2.7112 | 2.4345 | -10.21% | | Arabic moderation post, 1036 B | 3.9634 | 3.7680 | -4.93% | 3.8715 | 3.6589 | -5.49% | | Hindi moderation post, 1091 B | 2.6601 | 2.4853 | -6.57% | 2.5331 | 2.3453 | -7.41% | | Chinese moderation post, 1039 B | 2.3145 | 2.0789 | -10.18% | 2.1935 | 1.9339 | -11.84% | | Japanese moderation post, 1069 B | 3.2940 | 3.1229 | -5.20% | 3.1576 | 2.8807 | -8.77% | | Korean moderation post, 1098 B | 3.1239 | 2.8635 | -8.34% | 2.9995 | 2.7558 | -8.12% | | Mixed emoji moderation post, 1097 B | 2.6857 | 2.4525 | -8.68% | 2.5714 | 2.3065 | -10.30% | | English moderation thread, 65548 B | 169.3483 | 157.9180 | -6.75% | 161.4258 | 148.5095 | -8.00% | | Chinese moderation thread, 65620 B | 149.5828 | 139.0386 | -7.05% | 143.5457 | 131.7750 | -8.20% | | Split fields on two pipes, 4123 B | 2.5352 | 2.4895 | -1.80% | 2.7295 | 2.6258 | -3.80% | | Split fields on ::, 4099 B | 2.5143 | 2.5089 | -0.22% | 2.6946 | 2.7033 | +0.32% | | Parse HTTP headers, 65848 B | 0.8704 | 0.8702 | -0.02% | 0.8524 | 0.8262 | -3.07% | | Replace template placeholders, 4250 B | 7.0374 | 5.9181 | -15.91% | 6.4798 | 5.5455 | -14.42% | | Count {{order.id}} slots, 4250 B | 0.9989 | 0.8339 | -16.52% | 0.9404 | 0.7944 | -15.53% | Each build and case has three seconds of warmup and ten approximately one-second samples. There is one paired round, so results are preliminary. Elapsed A/A reached 2.32%. Small movements around this level are inconclusive. Delimiter and HTTP rows exercise unchanged short-search paths. Two 32-byte early-match controls take 3–4% more time on GCC. Searching 4096 a bytes for 63 a bytes followed by b takes 30.70% more time on GCC. That 64-byte case uses the existing wide table. Profiling records more branch misses, but the precise cause remains unresolved. Eight release binaries pass the string PHPT suite across six compiler configurations. Full PHP ASan/UBSan and extracted differential/mutation checks also pass. Intel elapsed results were excluded after failed A/A controls. Native ARM, Windows and 32-bit builds have not been tested. [Benchmark report, cycles, instructions, raw data and reproduction](https://github.com/ArtUkrainskiy/php-src-bench/tree/main/reports/compact-sunday).

« previous php.git-pulls (#40161) next »