Skip to content

[Repo Assist] perf: bulk-append unescaped character runs in JSON string parser#1715

Draft
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/perf-json-parsestring-bulk-append-ba53211cf351c3f2
Draft

[Repo Assist] perf: bulk-append unescaped character runs in JSON string parser#1715
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/perf-json-parsestring-bulk-append-ba53211cf351c3f2

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This is an automated pull request from Repo Assist, an AI assistant for this repository.

Summary

Optimises the JSON string parser (parseString in JsonValue.fs) to avoid per-character StringBuilder.Append calls by batching consecutive unescaped characters into a single Append(string, start, length) call.

Motivation

The inner loop of parseString previously called buf.Append(s.[i]) for every unescaped character. For a 100-character string value with no escape sequences that means 100 Append method calls — each with its own bounds-check, capacity-check, and write.

With this change, an unescaped run is tracked by a single chunkStart mutable. When an escape sequence (or the closing ") is reached, the whole run is flushed in one buf.Append(s, chunkStart, length) call. For the common case of strings with no escapes at all the total number of Append calls drops from O(n) to O(1).

Precedent

JsonStringEncodeTo (the serialisation counterpart) already uses exactly this chunk-flush pattern. This change applies the same technique symmetrically to the parser.

Change details

  • src/FSharp.Data.Json.Core/JsonValue.fsparseString: replace character-by-character Append with a chunkStart-tracking loop + flushChunk helper.
  • RELEASE_NOTES.md — version bump to 8.1.4.

No public API is changed; this is a pure implementation improvement.

Test Status

  • dotnet build src/FSharp.Data.Json.Core/FSharp.Data.Json.Core.fsproj — 0 errors, 4 pre-existing warnings
  • dotnet test tests/FSharp.Data.Core.Tests2896 passed, 0 failed (including all existing FsCheck property-based round-trip tests for parseString)

Generated by Repo Assist

Generated by 🌈 Repo Assist at {run-started}. Learn more.

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@1f672aef974f4246124860fc532f82fe8a93a57e

Replace per-character StringBuilder.Append(char) calls with
StringBuilder.Append(string, start, length) for consecutive runs of
unescaped characters in the JSON string parser.

For strings with no escape sequences (the common case in real-world
JSON), this reduces the number of Append calls from O(n) to O(1),
which should meaningfully speed up JsonValue.Parse on workloads
with many string values.

The approach mirrors what JsonStringEncodeTo already does for
serialisation: track a chunk start position and flush accumulated
characters as a bulk substring when an escape or closing quote is hit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

0 participants