Cache source lines in vertical_parameter_alignment - #6865
Open
Brett-Best wants to merge 1 commit into
Open
Conversation
`SourceLocationConverter.sourceLines` rebuilds every line of the file as a new `[String]` on each access, and the rule read it once per parameter. Hoisting it into a `lazy var` computes it once per file.
There was a problem hiding this comment.
Pull request overview
This PR improves the performance of the built-in vertical_parameter_alignment rule by avoiding repeated reconstruction of SourceLocationConverter.sourceLines (a computed property that materializes all file lines) during per-parameter alignment checks.
Changes:
- Cache
locationConverter.sourceLinesin the rule visitor via aprivate lazy var sourceLines. - Update
graphemeColumn(line:column:)to read from the cachedsourceLinesinstead of recomputing per access.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
vertical_parameter_alignment
Here's an example of your CHANGELOG entry: * Cache source lines in `vertical_parameter_alignment`.
[Brett-Best](https://github.com/Brett-Best)
[#issue_number](https://github.com/realm/SwiftLint/issues/issue_number)note: There are two invisible spaces after the entry's text. Generated by 🚫 Danger |
SimplyDanny
approved these changes
Aug 8, 2026
| // Computed once per file: `SourceLocationConverter.sourceLines` materializes every line of the | ||
| // file as a new `[String]` on each access, and `graphemeColumn(line:column:)` below reads it | ||
| // once per parameter, which is quadratic in the size of the file. | ||
| private lazy var sourceLines = locationConverter.sourceLines |
Collaborator
There was a problem hiding this comment.
We could also have this cached as part of SwiftLintFile+Cache to make it available to all rules.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
vertical_parameter_alignmentconverts a parameter's UTF-8 column into a grapheme-cluster column, so that declarations preceded by multi-byte characters are compared by visible alignment. It reads the file's source lines to do that:sourceLinesis a computed property in swift-syntax, and it rebuilds the entire file on each access:graphemeColumnis called once per parameter, for every declaration that has more than one parameter:So a file of m lines whose multi-parameter declarations hold p parameters in total allocates m × p strings in order to look at p lines. Hoisting the property into a
lazy varon the visitor computes it once per file.collection_alignmentalready carries this same hoist, for the same reason.Scaling
One file of n two-parameter functions,
--only-rule vertical_parameter_alignment, best of three:Before, the time roughly quadruples each time the count doubles; after, it is flat. The declarations are correctly aligned, so both builds report no violations on that file — all 4.47 seconds go to finding nothing.
Real projects
Unlike a defect that only shows up in unusually large files, this one is visible on ordinary code, because the rule touches the source lines for every parameter of every multi-parameter declaration. Both binaries run interleaved, five runs each, on an idle machine:
No behaviour change
With
--enable-all-rules, the violations are identical before and after — 590,289 on DuckDuckGo and 64,834 on realm-swift, 655,123 in total, matching once sorted. (The raw JSON order is not stable between runs of the same binary, since linting is parallel.) The test suite passes.🤖 Generated with Claude Code