commit 325a68b5234a664320fcfb1d28031b87bc98e7de
parent de8c3b62f7bba21c192e5a973d5f73ae94c2a0f8
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Sat, 13 Jun 2026 09:24:15 -0700
perf(lex): memchr-accelerate the splice pre-scan — skip non-backslash spans at NEON speed, no scalar whole-buffer pass
Diffstat:
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/lang/cpp/lex/lex.c b/lang/cpp/lex/lex.c
@@ -153,8 +153,21 @@ static void lex_fold_splices(Lexer* l, const char* src, size_t len) {
u32* spl;
size_t w, s, wcap;
l->next_splice = 0;
- for (i = 0; i + 1 < len; ++i)
- if (src[i] == '\\' && src[i + 1] == '\n') ++nspl;
+ /* Count `\<newline>` splices without a scalar whole-buffer pass: backslash is
+ * rare in C, so a memchr-driven sweep skips non-backslash spans at glibc-NEON
+ * speed (~1 instruction per 16-32 bytes) instead of testing every byte. The
+ * `-1` keeps bs[1] in range, so a trailing lone `\\` at src[len-1] is never
+ * counted as a splice — bit-exact with the old scalar `i + 1 < len` loop. */
+ if (len) {
+ const char* p = src;
+ const char* e = src + len;
+ while (p + 1 < e) {
+ const char* bs = (const char*)memchr(p, '\\', (size_t)(e - p) - 1);
+ if (!bs) break;
+ if (bs[1] == '\n') ++nspl;
+ p = bs + 1;
+ }
+ }
if (nspl == 0) {
l->src = src;
l->len = len;