perf: fix ~50% regression in FindIncludesInContent#21265
Conversation
Three targeted optimizations: 1. Fast-path byte check in ParseImportDirective before running regex 2. Eliminate redundant LegacyIncludeDirectivePattern regex by deriving isLegacy from captured groups of the first match 3. Replace bufio.Scanner allocation with strings.Lines in findIncludesInContent Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Hey A couple of things to address before this is ready for review:
If you'd like a hand adding the missing coverage, you can assign this prompt to your coding agent:
|
There was a problem hiding this comment.
Pull request overview
Improves the performance of FindIncludesInContent / import-directive parsing by reducing regex work on the hot path and avoiding per-call scanner allocations.
Changes:
- Adds a fast-path in
ParseImportDirectiveto skip regex evaluation for lines that can’t be directives. - Removes a redundant legacy-regex match by deriving legacy/new syntax from the primary regex capture groups.
- Replaces
bufio.Scannerline iteration withstrings.Linesto avoid per-call scanner/reader allocations.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| pkg/parser/import_directive.go | Adds directive fast-path and derives legacy/new syntax from existing regex captures to avoid extra regex work. |
| pkg/cli/remove_command.go | Uses strings.Lines to iterate content lines without allocating a scanner and returns nil error accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| } | ||
|
|
||
| return includes, scanner.Err() | ||
| return includes, nil // strings.Lines iterates over an in-memory string; no I/O errors can occur. |
FindIncludesInContentregressed to ~50,715 ns/op vs the historical ~33,698 ns/op. Three hot-path issues inParseImportDirectiveandfindIncludesInContent:IncludeDirectivePattern,isLegacywas re-evaluated via a secondLegacyIncludeDirectivePattern.MatchStringcall. The captured groups from the first match already encode this:matches[2] != ""iff the legacy alternative matched.@or{; a single byte check now rejects ordinary content lines before the regex engine is invoked.findIncludesInContentallocated abufio.Scanner+strings.Readerper call. Replaced withstrings.Lines(Go 1.25), which is allocation-free. Sincestrings.Readernever produces I/O errors,scanner.Err()was alwaysnil— no behavioral change.