-
Notifications
You must be signed in to change notification settings - Fork 116
Reduce allocations #1620
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
base: main
Are you sure you want to change the base?
Reduce allocations #1620
Conversation
|
/azp run |
|
The CI pipelines don't run the full set of tests because they don't have enough memory. :| |
This is a comment above a collection expression element here: https://github.com/microsoft/CsWin32/pull/1620/changes#diff-c2092e68e35fb17337bed2f51873aed87b806bd730c2976081ced52e47482ec3R416. In this particular case I don't agree with the rule. Should I just suppress it?
Then we are on the right track) |
No. We only suppress these rules in the generated files and some test files. Elsewhere we follow them. Just put the comment back where it was. |
|
Is the impact of this change measurable or meaningful? I'm not necessarily opposed, but eventually we will move away from this as a source generator and go exclusively to the build task version and so the overall allocations will matter quite a lot less in that world. Especially if your plan is to continue to try to clean up the code to address this, I'd like for you to set expectations about what your plan is. It's not worth our time on such large cleanup changes unless there's an impactful end goal we're working towards. |
I find it challenging to accuratly measure impact on the generator, but on my machine It is realtively easy to benchmark individual changes thouth. For instance, this one: using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
BenchmarkRunner.Run<Benchmarks>();
[MemoryDiagnoser(false)]
public class Benchmarks
{
private StatementSyntax _statement;
[GlobalSetup]
public void Setup()
{
_statement = SyntaxFactory.EmptyStatement();
}
[Benchmark]
public BlockSyntax CreateBlockByAdding()
{
return SyntaxFactory.Block().AddStatements(_statement);
}
[Benchmark]
public BlockSyntax CreateBlockDirectly()
{
return SyntaxFactory.Block(new SyntaxList<StatementSyntax>(_statement));
}
}My results:
My plan was to not heavily invest into perf, but rather collect low-hanging fruit and leave it in this sate. And as I mentioned in the PR description, IMHO this improves reading in most cases. E.g. it is easier to follow |
Roslyn nodes are immutable, meaning that creating them "step by step" using
.With...or.Add...methods allocates quite a lot of waste. So I refactored internal factory methods to take most common node parts as parameters directly and used collection expressions andparamsto avoid intermediate allocations arrays of nodes by replacing them with creating syntax lists directly. I believe this also makes code simpler and easier to follow.I ran the full set of tests, got a failure with unresolved
Marshalname (why didn't CI catch it earlier?), so also added qualification for it. I don't see value in separating this change, it is very little