Efcore: Infinite generic expansions cause efcore perform poorly with AOT compilation

Created on 24 Mar 2020  路  7Comments  路  Source: dotnet/efcore

Infinite generic expansions cause efcore perform poorly with AOT compilation

Original issue in CoreRT see https://github.com/dotnet/corert/issues/8052

Both ExecuteImplementation and ExecuteImplementationAsync call themselves with different generic arguments and lead to infinite generic expansions, which make efcore impossible to be AOT compiled.

Source:
https://github.com/dotnet/efcore/blob/master/src/EFCore/Storage/ExecutionStrategy.cs#L183
and
https://github.com/dotnet/efcore/blob/master/src/EFCore/Storage/ExecutionStrategy.cs#L276

Above recursive calls should be removed.

area-perf consider-for-current-release customer-reported propose-close type-enhancement

Most helpful comment

@ajcvickers You are right that this is a valid code. It is just a code with a very poor performance characteristics. This code is going "work" with CoreCLR, but it will cause the CoreCLR native images to be much larger than necessary.

When we find similar patterns in our frameworks, we generally fixed them. For example, System.Reflection.Metadata had a pattern that we have fixed. Other popular packages in ecosystem are happy to fix these performance problems as well. For example, System.Reactive fixed one of these infinite generic recursions as well.

If you are happy with EFCode having poor performance, on .NET Core w/ CoreCLR, feel free to close this again.

All 7 comments

This is perfectly valid C# code. Per discussion with .NET director, the AOT implementation needs to handle things like this.

@ajcvickers You are right that this is a valid code. It is just a code with a very poor performance characteristics. This code is going "work" with CoreCLR, but it will cause the CoreCLR native images to be much larger than necessary.

When we find similar patterns in our frameworks, we generally fixed them. For example, System.Reflection.Metadata had a pattern that we have fixed. Other popular packages in ecosystem are happy to fix these performance problems as well. For example, System.Reactive fixed one of these infinite generic recursions as well.

If you are happy with EFCode having poor performance, on .NET Core w/ CoreCLR, feel free to close this again.

@jkotas If there are performance issues. then we will address those appropriately by profiling, etc. in the normal way. Still, AOT needs to _work_ with this code.

those appropriately by profiling, etc

Make sure to look at binary sizes and startup times after AOT compilation, for the different AOT flavors that we are shipping in .NET.

I'm afriad that without Universal Shared Generics, infinite recursive generics may be impossible to be compiled with a Native AOT compiler. It only works when there's a JIT at runtime. Therefore, to support Native AOT compilation, it's necessary to rewrite the code and avoid infinite recursive generics.

@hez2010 EF Core 6.0 will likely have a focus area into perf and AOT (e.g. linking), so I'm hoping we'll take a full look at this.

@roji thanks, really looking forward to this. It's causing a problem when building any project that includes EFCore in its dependencies, which is one of the most widely used libraries for .NET out there. Definitely worth the effort. I've set up a repo there ( https://github.com/dotnet/runtimelab/issues/283 ) where you can replicate the issue if needed. I'll leave the repo alive until then. Thanks!

Was this page helpful?
0 / 5 - 0 ratings