Skip to content

zend_memnstr: Use a compact Sunday shift table for short needles - #25115

Open
ArtUkrainskiy wants to merge 1 commit into
php:masterfrom
ArtUkrainskiy:strpos-compact-sunday-pr
Open

ArtUkrainskiy wants to merge 1 commit into
php:masterfrom
ArtUkrainskiy:strpos-compact-sunday-pr

Conversation

@ArtUkrainskiy

@ArtUkrainskiy ArtUkrainskiy commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

I use a 256-byte Sunday shift table instead of a 1024-byte table for short needles. The PHP path selects it for 9–31-byte needles with at least 1024 bytes of haystack remaining. This reduces table initialization. The maximum shift is 32. Comparisons and shifts stay the same. Longer needles keep the integer table through a separate helper.

I measured saved application fixtures on Ryzen 9 5950X and Core i7-13700H. These are warmed, repeated PHP operations, not application throughput measurements. Moderation checks 12 phrases on a miss and stops at the seventh phrase on a hit.

Seven Intel cases slowed down in both the primary series and a fresh replication. Four Russian moderation cases at 64 KiB took +2.9–3.8% more time with Clang 18 in replication. Three HTML str_ireplace replacement lengths took +3.6–4.1% more time with Clang 20.

A synthetic 64-byte-needle search takes about 31% more time on AMD/GCC 15 through the integer-table path. The causes remain unresolved.

The selected product cases below show primary elapsed-time measurements against master at the branch base. Negative means less time. Each compiler column uses its own master. Absolute master time is in microseconds for AMD/GCC 15 only. † marks noisy observations, with separate replications in the report.

Case Master µs* AMD GCC15 AMD Clang21 Intel GCC13 Intel GCC14 Intel Clang18 Intel Clang20
English moderation, ~4 KiB, absent 11.0671 -9.06% -10.73% -0.48% -0.96% -1.71% -0.53%
English moderation, ~4 KiB, middle 7.0249 -8.88% -10.29% -0.14% -0.56% -1.90% -0.10%
English moderation, ~4 KiB, end 7.5198 -9.18% -10.68% +0.14% -0.59% -1.64% -0.21%
Russian moderation, ~4 KiB, absent 9.5386 -9.12% -10.64% -0.97% -0.91% -1.16% -1.18%
Russian moderation, ~4 KiB, middle 6.3119 -8.92% -10.93% -1.07% -0.55% -2.84% -1.24%
Russian moderation, ~4 KiB, end 6.8314 -8.86% -10.90% -0.14% -0.49% -2.52% -2.04%
Chinese moderation, ~4 KiB, absent 8.7645 -9.43% -13.31% -0.53%† -0.96% -1.75% -0.65%
Chinese moderation, ~4 KiB, middle 5.4898 -9.45% -11.12% -1.74% -1.13% -3.35% -2.22%†
Chinese moderation, ~4 KiB, end 5.8190 -9.33% -11.08% -2.05% -0.45% -2.45% -0.84%
strpos, order ID, ~4 KiB, near start 0.0263 -27.18% -21.67% -23.46% -26.57%† -9.99% -11.40%
substr_count, 3480 B, 17 matches 0.6714 -18.90% -20.71% -1.89% -11.38% -2.03%† -1.85%
str_replace, 3480 B, 17 matches 1.4390 -16.94% -17.88% -3.49% -5.44% -3.14%† -2.22%
explode, MIME message, 2878 B 0.5208 -10.18% -9.21% -3.16% -3.33% -3.34% -2.61%
str_ireplace, HTML, 2422 B, equal-length replacement 0.5250 -10.26% -9.42% -4.02% +2.10% -8.31%† +3.73%

Each case has five paired process rounds, 500 ms warmup and five approximately 200 ms samples per process. Empty-loop cost is subtracted. Deltas are medians of paired ratios.

All 205 fixtures pass exact expected-output checks on both binaries for all six compiler/machine configurations. ARM64, Windows and 32-bit builds were not measured.

Full report with cases, time, cycles, instructions, A/A controls, raw data and reproduction.

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.

1 participant