-
Notifications
You must be signed in to change notification settings - Fork 440
[Perf] Improve SyntaxRewriter visitation performance #2726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@swift-ci Please test |
CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxRewriterFile.swift
Outdated
Show resolved
Hide resolved
CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxRewriterFile.swift
Show resolved
Hide resolved
Too many changes in this PR. I will split this into several PRs. |
CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxRewriterFile.swift
Show resolved
Hide resolved
Similar treatment as 'SyntaxVisitor'. Reuse `Syntax.Info` when it's safe to do so (i.e. uniquely referenced)
7cbc241
to
5602b5c
Compare
@swift-ci Please test |
let rewritten = dispatchVisit(Syntax(absoluteRaw, parent: syntaxNode)) | ||
if rewritten.id != info.nodeId { | ||
dispatchVisit(&childNode) | ||
if childNode.raw.id != child.id { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously it compared SyntaxIdentifier
which takes the entire tree into account.
Now it compares RawSyntax.ID
because we only care the RawSyntax
here.
I.e. returning node.detached
is NOT considered "rewritten"
Factor out 'Syntax.Info' reusing into 'SyntaxNodeFactory' and 'SyntaxInfoRepository' as the backing storage. The underlying storage now uses a fixed length 'ManagedBuffer' to avoid 'ContiguousArray' overhead.
Use manually allocated 'UnsafeBufferPointer' to avoid 'ContiguousArray' overhead. Pre-initialize the buffer with the "old" layout at once, and update each element only when updated.
This was a generic function only for casting the result at the end. Hoist the casting part to the caller and make 'visitChilden()' non-generic.
Simpify the iteration code. Also, stop counting 'childIndex' as it can be retrieved from the absolute info.
Use 'SyntaxNodeFactory' in 'SyntaxVisitor' too. Thanks to the simplified implementation, it improves the performance a bit.
@swift-ci Please test |
@swift-ci Please test Windows |
1 similar comment
@swift-ci Please test Windows |
@swift-ci Please clean test Windows |
@swift-ci Please test |
1 similar comment
@swift-ci Please test |
@swift-ci Please test Linux |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Just a couple minor comments.
CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxRewriterFile.swift
Show resolved
Hide resolved
var rewrittens: ContiguousArray<Syntax> = [] | ||
// Keep 'SyntaxArena' of rewritten nodes alive until they are wrapped | ||
// with 'Syntax' | ||
var rewrittens: ContiguousArray<RetainedSyntaxArena> = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the performance characteristics of ContiguousArray
vs Array
here? I would expect Array
to be faster because it doesn’t need to move all elements if it runs out of space. And I don’t think we need the contiguous property here anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I haven't tried Array
here. interesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array always uses contiguous storage unless it's backed by NSArray
.
Although there's no particular reason to use ContiguousArray
, its implementation is simpler than Array
. So let's keep this as-is
@swift-ci Please test Linux |
@swift-ci Please test |
There's no performance reason to return 'nil'
Workaround for Windows command line length limitation
@swift-ci Please test |
@swift-ci Please test Windows |
Syntax.Info
reusing mechanism" inSyntaxVisitor
. Adopt it in bothSyntaxVisitor
andSyntaxRewriter