Conversation
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.
Summary
bin2hex()/hex2bin()currently run a plain byte-by-byte scalar loop. This adds a SIMD fast path (zend_simd.h: SSE2 on x86-64, NEON on aarch64) that processes 16 bytes at a time, falling back to the existing scalar loop for tails and, inhex2bin, for any chunk containing an invalid hex character — so error handling and output stay byte-for-byte identical to before.Who benefits: anything hex-encoding/decoding hashes, checksums, UUIDs, MAC addresses, tokens, or signatures —
hash()/md5()/sha1()formatting, crypto/signature verification, logging, cache/session keys. This is the dominant real-world call shape for both functions.Precedent: vectorizing hot byte/string functions via this header is established practice —
stripslashesSSE2, bcmath ported tozend_simd.h, SSE2mb_strlen,zend_simd.hitself.Benchmarks
Real hardware,
phptcorrectness gate passing (ALL OK) before timing, on both hosts:Crypto/hash-sized inputs
bin2hexx86bin2hexarm64hex2binx86hex2binarm644B/6B show no win on either function — both are below the size where the SIMD path even engages (16 bytes for
bin2hex, one full 32-char chunk forhex2bin), so those calls run the unmodified scalar loop. Not a regression, nothing changed for them.Full corpus (throughput, branch/patched vs baseline/unpatched)
bin2hexx86bin2hexarm64hex2binx86hex2binarm64Allocator-boundary step-down, not a SIMD regression
straceon x86, 20 calls each: crossing the ~2MB output-buffer threshold takesbin2hexfrom 6munmap/24mmapcalls to 65/63 — the allocator switches from heap reuse to a freshmmap/munmappair almost every call. That fixed syscall cost is the same for branch and baseline, but eats a much bigger share of the branch's now-tiny per-call time, which is why the throughput ratio compresses from ~10× down to 1.4–3× above 1MB rather than the branch getting slower in absolute terms.