-
Notifications
You must be signed in to change notification settings - Fork 22
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
Performance of the source generator. #39
Comments
Unfortunately you may be right. About true in the filter, I had plans to figure out how to separate only meaningful changes, but for now it's just the way it is. As for syntaxContext - I need both a syntax node and a semantic model. And I'll play with changes in IDE and try to understand if there is any profit from incremental API. PS: You are doing an interesting project! |
@NikolayPianikov you may benefit from incrementability test (see the reference above) and from new articles of Andrew Lock (this is about pipeline building and what to allowed to inject in).
please pay attention that syntax provider reevaluated all filtered nodes even if only one node has changed: In general, I asked Rolsyn members about our topic (DI) in conjunction with source generators, and the answer is not good: looks like it is impossible to implement source-gen'd DI efficiently. It is the reason I stopped my project, I see no future here :\ Good luck! |
Whoa!! How bad is the performance? Are we talking about visual studio freezing on file changes or slow build times? |
I did not estimate.
yeah, we are talking about IDE experience only. It is the main sufferer. Please consider:
It does not matters for a small projects, the performance is good. But for very big codebases (for example Rolsyn-scale) these source generators are able to slow down you IDE experience to the level of seconds, if I remember the numbers correctly. It is the reason I positioned my Dpdt to the library authors and choose to inject source code inside the user project. Libraries are smaller than applications. Sorry for these news. Remember, I may be wrong! |
Yeah, I am considering porting very large codebase. If I understand correctly the source generators, this issue should be present only for IIncrementalGenerators as they are evaluated on key press. Other type of generators should be run only during build and this won't be a problem. Also our solution is over 250+ projects. I believe if I keep incremental source generators only in .exe projects that should not affect the code experience in other projects? Am I right? |
AFAIK there are 2 types of SG: incremental and the old
Sorry, I don't know. Consider organize an experiment. In general, I'm sure everyone agrees that no one need to rebuild all DI trees for every key press. I guess the more correct way is to rebuild DI tree in a pre build phase somehow... But this have disadvantages and I chose to stop the development... |
The first version of Pure.DI was written using a non-incremental API. And I haven't noticed at least that the new API has become worse. About performance. I have some public projects that contain quite large and complex compositions of objects, like this. And in the IDE I don't feel any problems at all. Private projects I can't show you. I periodically collect statistics on large compositions and found that CPU is wasted on:
The rest of the code runs fast. Besides, I have test for large configs and in general the generator shows itself well. I don't think that with the current Roslyn API it is possible to reuse metadata from previous syntax trees in any way. The main place of optimization for me is to limit the set of trees to be analized and I plan to do that |
@ekalchev thx for this, will definitely read it. |
The topic discussed here, bothers me, because I need to make a decision to transition huge solution 250+ csproj files from Unity DI to Pure.DI and I don't want to make the life of many developers miserable by degrading the performance of Visual Studio. I see some concerns about the performance of source generators here dotnet/roslyn#55518 I wonder if Pure.DI really needs to generate code on each keystroke in Visual Studio and if it doesn't can I find a way to turn it off? This kind of source generator doesn't need to generate classes on the fly so you can call their interface immediately after typing something that triggers the source generation - you don't need that. I wonder if it is possible to avoid having Pure.DI generator included in MSBuild inline script completely and only add it inside a MSBuild Target before Build. This way the code will be generated only during build and not on a keystroke
Alternatively, is it possible to have a MSBuild variable similar to DisableFrameworkReferenceAnalyzers that turns off Pure.DI generator and have this variable set for debug builds for example? |
I have looked for performance and found no significant performance issues. Yes Roslyn is not fast with the semantic model. <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Generator>False</Generator>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pure.DI" Version="2.1.9" Condition="'$(Generator)'=='True'">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project> The MSBUILD variable "Generator" will allow you to disable and enable the generator from the MSBUILD variable. You can do this for multiple projects at once if you place this logic in the Directory.Build.props file If it would be more convenient I can add a special flag to enable and disable generation. |
Switching to msbuild stage has huge drawbacks and (from my pov) is not an option. one will no access to roslyn metadata inside msbuild step, so it will be necessary to rebuild such model again, which is horrible for compilation timings. I proposed idea somewhere inside Roslyn to share Roslyn metadata across msbuild steps. That's a great idea, I think, because projects like this (and mine) will generate its code only once, at the start of compilation. But, Roslyn team is small and 100% its time is spent for every year race of new C#. No hope)) You can generate a huge fake solution and benchmark its performance in the scope of Pure.DI. In other hand, if your project suffers from poor DI-performance, I guess honestly, that this problem should be solved in some different way instead of switching to ISG-based DI. |
My main motivation for source generated DI is that reflection based DI, require loading all dotnet assemblies at process start so the code can discover the constructor parameters. This may be ok for web apps but it is huge drawback for Desktop app where you need fast startup and delay the load of some assemblies or not load them all at if they are not needed in some scenarios. I am talking about hundreds of assemblies. I believe source generated DI will solve this problem, because the generated factories will load the assembly only when the type from this assembly is needed. Add to this reflection code on each type constructor and I believe I can half the startup time of my application and stop the degrading startup with adding more and more types and assemblies in the future. Why do think this is not valid reason to switch to source generated DI?
I didn't know there was an option to turn it off. I think this will be enough to find a MSBuild solution if there are performance issues |
is that a real data or theoretical estimation? I'm just curious. did you try Native AOT deployment? |
it is estimation based on profiling data. |
@ekalchev if you define the parameters of your big solution, I can create a test solution and test its performance with the code generator. By parameters I mean:
|
Hello!
I'm not sure about these topics, so I post them here only fyi.
ISourceGenerator
?As an author of similar library https://github.com/lsoft/DpDtInject I found no way to effiently apply incremental source generators for the task of DI. If I wrong, could you share where did I miss?
Good luck! Thanks!
The text was updated successfully, but these errors were encountered: