diff options
| author | Fuwn <[email protected]> | 2026-02-05 10:52:14 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-05 10:52:14 +0000 |
| commit | f1dfe6b1b13e60d4a0bffab576e617b148887960 (patch) | |
| tree | 3e640d4b82997d6cf8c00a583fa689a08201e0ca /engine/engine.go | |
| parent | perf: Reduce allocations and syscalls in formatting pipeline (diff) | |
| download | iku-f1dfe6b1b13e60d4a0bffab576e617b148887960.tar.xz iku-f1dfe6b1b13e60d4a0bffab576e617b148887960.zip | |
perf(engine): Write formatted output directly into strings.Builder
Diffstat (limited to 'engine/engine.go')
| -rw-r--r-- | engine/engine.go | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/engine/engine.go b/engine/engine.go index 15ee568..2ce21f3 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -14,8 +14,8 @@ type Engine struct { CommentMode CommentMode } -func (e *Engine) Format(events []LineEvent) []string { - resultLines := make([]string, 0, len(events)) +func (e *Engine) format(events []LineEvent, resultBuilder *strings.Builder) { + hasWrittenContent := false previousWasOpenBrace := false previousStatementType := "" previousWasComment := false @@ -24,7 +24,13 @@ func (e *Engine) Format(events []LineEvent) []string { for eventIndex, event := range events { if event.InRawString { - resultLines = append(resultLines, event.Content) + if hasWrittenContent { + resultBuilder.WriteByte('\n') + } + + resultBuilder.WriteString(event.Content) + + hasWrittenContent = true continue } @@ -43,7 +49,7 @@ func (e *Engine) Format(events []LineEvent) []string { currentIsTopLevel := event.HasASTInfo && event.IsTopLevel currentIsScoped := event.HasASTInfo && event.IsScoped - if len(resultLines) > 0 && !previousWasOpenBrace && !event.IsClosingBrace && !event.IsCaseLabel { + if hasWrittenContent && !previousWasOpenBrace && !event.IsClosingBrace && !event.IsCaseLabel { if currentIsTopLevel && previousWasTopLevel && currentStatementType != previousStatementType { if !(e.CommentMode == CommentsFollow && previousWasComment) { needsBlankLine = true @@ -62,17 +68,17 @@ func (e *Engine) Format(events []LineEvent) []string { nextIndex := e.findNextNonComment(events, eventIndex+1) if nextIndex >= 0 { - next := events[nextIndex] + nextNonCommentEvent := events[nextIndex] - if next.HasASTInfo { - nextIsTopLevel := next.IsTopLevel - nextIsScoped := next.IsScoped + if nextNonCommentEvent.HasASTInfo { + nextIsTopLevel := nextNonCommentEvent.IsTopLevel + nextIsScoped := nextNonCommentEvent.IsScoped - if nextIsTopLevel && previousWasTopLevel && next.StatementType != previousStatementType { + if nextIsTopLevel && previousWasTopLevel && nextNonCommentEvent.StatementType != previousStatementType { needsBlankLine = true } else if nextIsScoped || previousWasScoped { needsBlankLine = true - } else if next.StatementType != "" && previousStatementType != "" && next.StatementType != previousStatementType { + } else if nextNonCommentEvent.StatementType != "" && previousStatementType != "" && nextNonCommentEvent.StatementType != previousStatementType { needsBlankLine = true } } @@ -81,10 +87,16 @@ func (e *Engine) Format(events []LineEvent) []string { } if needsBlankLine { - resultLines = append(resultLines, "") + resultBuilder.WriteByte('\n') + } + + if hasWrittenContent { + resultBuilder.WriteByte('\n') } - resultLines = append(resultLines, event.Content) + resultBuilder.WriteString(event.Content) + + hasWrittenContent = true previousWasOpenBrace = event.IsOpeningBrace || event.IsCaseLabel previousWasComment = event.IsCommentOnly @@ -99,21 +111,25 @@ func (e *Engine) Format(events []LineEvent) []string { } } - return resultLines + resultBuilder.WriteByte('\n') } func (e *Engine) FormatToString(events []LineEvent) string { - lines := e.Format(events) - lines = append(lines, "") + var resultBuilder strings.Builder - return strings.Join(lines, "\n") + resultBuilder.Grow(len(events) * 40) + e.format(events, &resultBuilder) + + return resultBuilder.String() } func (e *Engine) FormatToBytes(events []LineEvent) []byte { - lines := e.Format(events) - lines = append(lines, "") + var resultBuilder strings.Builder + + resultBuilder.Grow(len(events) * 40) + e.format(events, &resultBuilder) - return []byte(strings.Join(lines, "\n")) + return []byte(resultBuilder.String()) } func (e *Engine) findNextNonComment(events []LineEvent, startIndex int) int { |