Comments (18)
@jnm2 here's my first pass at creating an incremental generator which should reduce the amount of time iterating through syntax trees:
https://github.com/YairHalberstadt/stronginject/tree/incremental-generators
How annoying would it be to ask you to build and reference from source, and tell me if it reduces light bulb wait time?
Thanks!
from stronginject.
In the largest project where we use StrongInject, this is causing the light bulb to take 5-20 seconds to appear and 5-20 seconds to preview or apply any suggested action. (Or invoke renames, etc.)
from stronginject.
I'm investigating the work required to make this change.
from stronginject.
If it's mainly the syntax trees that are expensive, then it should be relatively straightforward to use an incremental generator for that step.
from stronginject.
Easy. I checked out that branch (24057fd), added StrongInject.csproj and StrongInject.Generator.csproj to the solution in question, and replaced the StrongInject package reference with a project reference to StrongInject.csproj and added an additional project reference with OutputItemType="Analyzer"
to StrongInject.Generator.csproj to the project that needs source generation. The solution builds fine.
I then restarted VS, built again (incremental build succeeded immediately), and invoked the light bulb on random things. It seems like the light bulb takes the same amount of time to open after any source edit, and it seems like the fixes take 2-3 times longer to preview or apply than they did before. Very unscientific perceptual guess.
I'm not sure what my testing methodology should be. Sam said:
the problem here was indirect. extreme allocations from StrongInject are leading to long GC pauses. So far attributed 37GB allocs to it in your trace
So if the light bulb and fixes started applying very fast, I'd potentially still have to spend some time doing real work in the solution in order to fully evaluate the improvement?
I also checked out the commit in this project just prior to introducing StrongInject, and the light bulb and fixes became perceptually instant. That gives me something to perceptually compare to. Checking out the commit that introduced StrongInject brings back the long waits.
from stronginject.
Well that's disappointing...
Can I get an idea for how big your project is, say in number of lines of code and number of files? And do you know if you get similar slowness in CLI build times, or when working in VSCode or rider? I want to make sure that I can reproduce this without having access to Visual Studio.
from stronginject.
2510 files, 280k lines including blanks. I couldn't see a significant effect in CLI build times. (I got anywhere from 1-3 seconds additional CLI build time when I initially added StrongInject, but my recent comparisons fluctuated enough that it might be closer to 0 seconds.)
Rider's light bulb is always instant and the fixes vary from instant to less than a second to apply, for comparable operations.
from stronginject.
Ok, that's a reasonable size for a single project. As a temporary workaround have you considered separating the StrongInject code to a different project?
from stronginject.
By introducing a new entry point assembly that defines the container? (All application-level code where the light bulb needs to work is in classes injected by StrongInject.)
Every project in the solution references StrongInject, also, because Owned<T>
is sprinkled throughout. Does that incur a cost, or is the cost delayed until an IContainer<T>
implementation is seen?
from stronginject.
I imagine everything will incur the cost because there's no way to reference StrongInject without the generator.
from stronginject.
@sharwell I've created an incremental generator which I assume should avoid scanning all trees on every edit, but according to @jnm2 it's not improving performance. Would you be able to advise if it does what it says in the tin?
The generator is at https://github.com/YairHalberstadt/stronginject/tree/incremental-generators
from stronginject.
I wonder if ExcludeAssets="analyzers"
affects generators.
from stronginject.
Busy today but will try to take a look later
from stronginject.
-
The largest single allocation (6GB) is
GenericDecoratorsResolver.ResolveDecorators
, which would be fixed by either calling this method less frequently or changing it to not useyield return
. -
There is nearly 7.5GB allocations coming from
GenericRegistrationsResolver.TryResolve
and methods which it calls, mostly from various use of LINQ
from stronginject.
@sharwell @jnm2 Is there some way you can share the full trace with me?
Also what's the easiest way to visualise the trace?
Thanks!
from stronginject.
(I shared dotMemory and dotTrace traces of devenv.exe while invoking the light bulb directly with Yair, and it matches closely with Sam's screenshot above)
from stronginject.
I submitted #182 to fix TryResolve and ResolveDecorators.
from stronginject.
Fixed by #180
from stronginject.
Related Issues (20)
- Inject Func<Owned<T>> parameters HOT 1
- [Feature/Idea] Support for primary constructor generator HOT 2
- Innermost hasAwaitStarted catch block is a no-op and could be omitted HOT 3
- Update xamarin sample to maui
- 'registerAs' parameter for FactoryAttribute HOT 9
- IOwned<out T> HOT 4
- Convenience methods for creating Owned<T> instances HOT 3
- Permitting null instead of empty delegate for Owned<T> and AsyncOwned<T> HOT 2
- Add diagnostic if any registered method return types are by ref.
- Circular dependency check is too restrictive for delegates HOT 23
- SI1103 warning location forces suppression to be all or nothing HOT 6
- Separate Microsoft DI from Asp.Net Core HOT 2
- Retrieving design-time info about registrations HOT 5
- StrongInject Source Generator API HOT 1
- Confusing use of the term 'delegate parameters' in the readme HOT 2
- Support decorator factories that aren't gratuitously generic HOT 4
- Misleading info in README HOT 2
- Generic interface registration HOT 1
- asp.net middleware support
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from stronginject.