efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Compiled model performance trends

Open ajcvickers opened this issue 4 months ago • 9 comments

In investigating the compiled model changes in EF9, I noticed that things were taking quite a lot longer than expected, so I did some analysis.

The model here is the one used in the samples: https://github.com/dotnet/EntityFramework.Docs/tree/main/samples/core/Miscellaneous/CompiledModels

The first issue is that, for this sample model with 449 entity types, 6390 properties, and 720 relationships, the startup time is now worse when using a compiled model.

EF version Normal (s) Compiled model (s)
EF Core 6 3.71 0.93
EF Core 7 4.07 1.04
EF Core 8 4.52 3.37
EF Core 9 4.48 5.24
image

By startup time, I mean wall clock time to run the following:

using (var context = new BlogsContext())
{
    entityCount = context.Model.GetEntityTypes().Count();
}

My suspicion that a lot of this is assembly loading and/or JIT, based on the increase in DLL size across releases:

EF version Normal (MB) Compiled model (MB)
EF Core 6 0.9 2
EF Core 7 0.9 2
EF Core 8 0.9 8
EF Core 9 0.9 20
image

Related to all this is that the time to run dotnet ef dbcontext optimize on this same model has increased very dramatically in EF9.

EF version Time to run dbcontext optimize (s)
EF Core 6 11
EF Core 7 11
EF Core 8 40
EF Core 9 107
image

ajcvickers avatar Apr 06 '24 11:04 ajcvickers

Note: see profiling session done by @muzopraha in #33495:

image

roji avatar Apr 09 '24 12:04 roji

This also shows regression for non-compiled models. Is a separate issue needed to track that?

stevendarby avatar Apr 13 '24 08:04 stevendarby

@stevendarby yeah, that's true - we'll discuss this in the team as well.

roji avatar Apr 13 '24 08:04 roji

@stevendarby @roji We discussed the regression in 8.0 at the time, and it was considered acceptable because if people had slow model building performance then they could use compiled models! Oh, the irony.

ajcvickers avatar Apr 13 '24 09:04 ajcvickers

@ajcvickers Irony aside, it's also not really true in all cases - for example, if you use query filters?

stevendarby avatar Apr 13 '24 09:04 stevendarby

@stevendarby Agreed.

ajcvickers avatar Apr 13 '24 09:04 ajcvickers

Is it a reasonable workaround, for now, to compile the model with EF Core 7, but then upgrade packages and run with v8 or v9? It doesn't crash and burn immediately, but I'd like to know if that's a completely unsupported mix. Thanks.

Not sure how surprising this is, but when I encountered this issue, I discovered that AOT doesn't really improve the model init time of compiled models. (Leaving aside the fact queries won't run on AOT).

iainnicol-hymans avatar Apr 16 '24 09:04 iainnicol-hymans

Is it a reasonable workaround, for now, to compile the model with EF Core 7, but then upgrade packages and run with v8 or v9? It doesn't crash and burn immediately, but I'd like to know if that's a completely unsupported mix. Thanks.

No, it's completely unsupported. A "better" workaround would be to use some post-processing script to remove the slow calls added in the newer code. Most of them will be just computed lazily when not using NativeAOT.

AndriySvyryd avatar Apr 19 '24 18:04 AndriySvyryd

This is the proposed action plan to deal with this regression:

  • [ ] By default generate a compiled model equivalent to what EF Core 6 would generate, with CLI switches that would add more code to the compiled model (For NativeAOT fully eager generation is required)
  • [ ] #31370
  • [ ] Look for opportunities to generate less code by leveraging defaults (in particular, for provider-specific configuration)
  • [ ] Fully qualify (including the return type) the generated lambdas
  • [ ] "Lift" reused lambdas, comparers and type mappings to a common location
  • [ ] By default, don't use the backing field for non-virtual auto-props
  • [ ] Inline property accessors to avoid lambdas with closures (this would require new API on InternalEntityEntry)
  • [ ] Don't generate lambda expressions for NativeAOT (#32717)

AndriySvyryd avatar Apr 22 '24 23:04 AndriySvyryd