Skip to content

Reduce allocations in StructuredStringBuilder - #24

Open
Illustar0 wants to merge 2 commits into
Noggog:devfrom
Illustar0:perf/structured-string-builder
Open

Illustar0 wants to merge 2 commits into
Noggog:devfrom
Illustar0:perf/structured-string-builder

Conversation

@Illustar0

Copy link
Copy Markdown

StructuredStringBuilder is on the hot path of every Loqui Print, and it allocated a lot more than the text it produced. Every Append concatenated onto the last line again and split its input with string.Split plus a closure. Every AppendLine allocated a Line scope and a fresh indentation string through a StringBuilder. StartsWith(Environment.NewLine) also compared using the current culture, which turned out to be the slowest part.

This keeps the line being written in a StringBuilder and only turns it into a string once the line ends. It splits on new lines with an ordinal IndexOf, and writes indentation straight into the line. DepthStr and the rest of the public API stay as they are.

Printing ~1000 lines the way Loqui's generated Print does:

Method Before After
PrintFields 968 µs / 580 KB 96 µs / 169 KB
PrintToString 554 µs / 307 KB 36 µs / 113 KB

This should not change any output. The first commit adds tests that pin the current behavior; they pass both before and after the change. The only difference is that the debug-only LineAppended no longer sees the indentation strings, or the empty line the constructor used to append.

- Cover indentation, continuing a line, AppendItem, Empty and editing lines
- Keep the line being written in a StringBuilder rather than concatenating it on every Append
- Split on new lines with ordinal IndexOf instead of string.Split and a closure
- Compare new lines ordinally rather than with the current culture
- Indent in place instead of allocating a Line scope and an indentation string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant