-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SwiftSyntax] Make Syntax nodes structs instead of classes #14122
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
[SwiftSyntax] Make Syntax nodes structs instead of classes #14122
Conversation
@swift-ci please smoke test |
+1 I believe this is the right way to go! |
This is an interesting experiment, @harlanhaskins . The second drawback is the one I'm not a big fan of. We do see our clients using Set/Dictionary to track Syntax nodes in multi-pass analysis (this patch may break their codebase). Can we reconcile the hashable convenience and the awesome memory efficiency? |
Well, hope is not completely lost. You can still have a set of, say, |
@swift-ci please smoke test |
Another thing: I think |
bfeb1d4
to
e21878d
Compare
@nkcsgexi So, this seems to be the best I can get the branch. All the existing Also, we lose the ability to use |
@swift-ci please smoke test |
To measure the performance impact of this change, I adjusted Silt's parser to use struct-based Syntax nodes and had it parse a 100,000-line file. Our AST, prior to this change, allocated 400MB, then kept allocating more memory as we dumped the AST until we reached 2.2GB while printing the 20,000th line. I killed the program after there because memory was climbing linearly. After making this change, we got through all 100,000 lines allocating 1.75GB, which (though excessive) is a significant improvement. |
@harlanhaskins I think you're right. Judging from the experiment results, this is a great performance improvement that worths the dropping of hashability. Feel free to merge if when you feel ready. Thanks! 👍 |
@swift-ci please smoke test |
Thanks for reviewing! |
…#14122) * [Experiment] Make Syntax nodes structs instead of classes * [Experiment] Add Hashable conformance to concrete types * Fix pep8 violation * Remove AnySyntax, explicitly specialize SyntaxCollection nodes * Refine the comment for SyntaxCollection nodes
This patch, more in line with how I hoped we could structure the API, moves from a class-based model with Syntax as a superclass to a protocol-based model where each struct conforms to Syntax.
This has benefits and drawbacks:
Benefits
(I noticed allocations of these things was a problem when I profiled a run of Silt's parser and noticed a huuuuge number of Syntax node allocations)
Drawbacks
Syntax
/ExprSyntax
/DeclSyntax
, etc. nodes can no longer be created directly.Syntax
can no longer be Hashable because that precludes its use as an existential. Instead of comparing twoSyntax
nodes with anEquatable
conformance, one must conditionally cast them down to the same type. There is an overload for==
, so most users won't feel the pain of this. But it does mean you can no longer make aSet<Syntax>
, onlySet
s of concrete Syntax nodes.I'm leaning towards the drawbacks outweighing the benefits, but I personally think it's unreasonable for each of these nodes to have to be an allocation.