From 4528b1fe64d237b5c206578f4aed201a7850fa66 Mon Sep 17 00:00:00 2001 From: He-Pin Date: Mon, 11 May 2026 16:52:40 +0800 Subject: [PATCH] perf: scan lf text-block lines with indexOf Motivation: Large text blocks spend visible parser time finding line boundaries with a Scala character loop. Modification: Use String.indexOf for single-character LF separators in the bulk text-block scanner while preserving the existing CRLF and multi-character separator path. Result: LF text-block parsing uses the platform string search fast path without changing text-block semantics. --- sjsonnet/src/sjsonnet/Parser.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sjsonnet/src/sjsonnet/Parser.scala b/sjsonnet/src/sjsonnet/Parser.scala index e4ad6bbd..b06fb98e 100644 --- a/sjsonnet/src/sjsonnet/Parser.scala +++ b/sjsonnet/src/sjsonnet/Parser.scala @@ -413,11 +413,17 @@ class Parser( else if (pos + indentLen <= dataLen && data.regionMatches(pos, indent, 0, indentLen)) { val afterIndent = pos + indentLen // Find line end (next separator char) - var lineEnd = afterIndent - while (lineEnd < dataLen && sep.indexOf(data.charAt(lineEnd)) < 0) lineEnd += 1 + val lineEnd = + if (sepLen == 1) data.indexOf(sep.charAt(0), afterIndent) + else { + var i = afterIndent + while (i < dataLen && sep.indexOf(data.charAt(i)) < 0) i += 1 + i + } // Verify full separator at lineEnd if ( - lineEnd + sepLen <= dataLen && data.charAt(lineEnd) == sep.charAt(0) && + lineEnd >= 0 && lineEnd + sepLen <= dataLen && + data.charAt(lineEnd) == sep.charAt(0) && (sepLen == 1 || data.charAt(lineEnd + 1) == sep.charAt(1)) ) { // Zero-copy bulk append: extra whitespace + content + separator (skipping indent)