Skip to content

Commit 8d18b1c

Browse files
authored
Fix to #35212 - Query/Perf: Compile identifier lambdas passed to PopulateIncludeCollection rather than inline (#35213)
PopulateIncludeCollection (as well as couple other methods) take a number of delegate arguments. For scenarios with significant number of entities we see significant perf improvement when these delegates are compiled (like we used to do in EF8), rather than inlined. Fixes #35212
1 parent 20201da commit 8d18b1c

File tree

1 file changed

+94
-14
lines changed

1 file changed

+94
-14
lines changed

src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.cs

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -856,16 +856,40 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
856856
QueryCompilationContext.QueryContextParameter,
857857
_dataReaderParameter);
858858

859+
var parentIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
860+
parentIdentifierLambda.Compile(),
861+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
862+
parentIdentifierLambda,
863+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
864+
"parentIdentifierLambda",
865+
typeof(Func<QueryContext, DbDataReader, object[]>));
866+
859867
var outerIdentifierLambda = Lambda(
860868
Visit(relationalCollectionShaperExpression.OuterIdentifier),
861869
QueryCompilationContext.QueryContextParameter,
862870
_dataReaderParameter);
863871

872+
var outerIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
873+
outerIdentifierLambda.Compile(),
874+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
875+
outerIdentifierLambda,
876+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
877+
"outerIdentifierLambda",
878+
typeof(Func<QueryContext, DbDataReader, object[]>));
879+
864880
var selfIdentifierLambda = Lambda(
865881
Visit(relationalCollectionShaperExpression.SelfIdentifier),
866882
QueryCompilationContext.QueryContextParameter,
867883
_dataReaderParameter);
868884

885+
var selfIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
886+
selfIdentifierLambda.Compile(),
887+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
888+
selfIdentifierLambda,
889+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
890+
"selfIdentifierLambda",
891+
typeof(Func<QueryContext, DbDataReader, object[]>));
892+
869893
_inline = false;
870894

871895
_includeExpressions.Add(
@@ -876,8 +900,8 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
876900
_dataReaderParameter,
877901
_resultCoordinatorParameter,
878902
entity,
879-
parentIdentifierLambda,
880-
outerIdentifierLambda,
903+
parentIdentifierLambdaCompiled,
904+
outerIdentifierLambdaCompiled,
881905
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
882906
navigation,
883907
LiftableConstantExpressionHelpers.BuildNavigationAccessLambda(navigation),
@@ -905,9 +929,9 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
905929
QueryCompilationContext.QueryContextParameter,
906930
_dataReaderParameter,
907931
_resultCoordinatorParameter,
908-
parentIdentifierLambda,
909-
outerIdentifierLambda,
910-
selfIdentifierLambda,
932+
parentIdentifierLambdaCompiled,
933+
outerIdentifierLambdaCompiled,
934+
selfIdentifierLambdaCompiled,
911935
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
912936
relationalCollectionShaperExpression.ParentIdentifierValueComparers
913937
.Select(x => (Func<object, object, bool>)x.Equals).ToArray(),
@@ -980,6 +1004,14 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
9801004
QueryCompilationContext.QueryContextParameter,
9811005
_dataReaderParameter);
9821006

1007+
var parentIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1008+
parentIdentifierLambda.Compile(),
1009+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1010+
parentIdentifierLambda,
1011+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1012+
"parentIdentifierLambda",
1013+
typeof(Func<QueryContext, DbDataReader, object[]>));
1014+
9831015
_inline = false;
9841016

9851017
innerProcessor._inline = true;
@@ -989,6 +1021,14 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
9891021
QueryCompilationContext.QueryContextParameter,
9901022
innerProcessor._dataReaderParameter);
9911023

1024+
var childIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1025+
childIdentifierLambda.Compile(),
1026+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1027+
childIdentifierLambda,
1028+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1029+
"childIdentifierLambda",
1030+
typeof(Func<QueryContext, DbDataReader, object[]>));
1031+
9921032
innerProcessor._inline = false;
9931033

9941034
_includeExpressions.Add(
@@ -999,7 +1039,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
9991039
_dataReaderParameter,
10001040
_resultCoordinatorParameter,
10011041
entity,
1002-
parentIdentifierLambda,
1042+
parentIdentifierLambdaCompiled,
10031043
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
10041044
navigation,
10051045
LiftableConstantExpressionHelpers.BuildNavigationAccessLambda(navigation),
@@ -1029,7 +1069,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
10291069
CreateReaderColumnsExpression(readerColumns, _parentVisitor.Dependencies.LiftableConstantFactory),
10301070
Constant(_detailedErrorsEnabled),
10311071
_resultCoordinatorParameter,
1032-
childIdentifierLambda,
1072+
childIdentifierLambdaCompiled,
10331073
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
10341074
relationalSplitCollectionShaperExpression.IdentifierValueComparers
10351075
.Select(x => (Func<object, object, bool>)x.Equals).ToArray(),
@@ -1148,16 +1188,40 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
11481188
QueryCompilationContext.QueryContextParameter,
11491189
_dataReaderParameter);
11501190

1191+
var parentIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1192+
parentIdentifierLambda.Compile(),
1193+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1194+
parentIdentifierLambda,
1195+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1196+
"parentIdentifierLambda",
1197+
typeof(Func<QueryContext, DbDataReader, object[]>));
1198+
11511199
var outerIdentifierLambda = Lambda(
11521200
Visit(relationalCollectionShaperExpression.OuterIdentifier),
11531201
QueryCompilationContext.QueryContextParameter,
11541202
_dataReaderParameter);
11551203

1204+
var outerIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1205+
outerIdentifierLambda.Compile(),
1206+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1207+
outerIdentifierLambda,
1208+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1209+
"outerIdentifierLambda",
1210+
typeof(Func<QueryContext, DbDataReader, object[]>));
1211+
11561212
var selfIdentifierLambda = Lambda(
11571213
Visit(relationalCollectionShaperExpression.SelfIdentifier),
11581214
QueryCompilationContext.QueryContextParameter,
11591215
_dataReaderParameter);
11601216

1217+
var selfIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1218+
selfIdentifierLambda.Compile(),
1219+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1220+
selfIdentifierLambda,
1221+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1222+
"selfIdentifierLambda",
1223+
typeof(Func<QueryContext, DbDataReader, object[]>));
1224+
11611225
_inline = false;
11621226

11631227
var collectionParameter = Parameter(relationalCollectionShaperExpression.Type);
@@ -1171,8 +1235,8 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
11711235
QueryCompilationContext.QueryContextParameter,
11721236
_dataReaderParameter,
11731237
_resultCoordinatorParameter,
1174-
parentIdentifierLambda,
1175-
outerIdentifierLambda,
1238+
parentIdentifierLambdaCompiled,
1239+
outerIdentifierLambdaCompiled,
11761240
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
11771241
collectionAccessor,
11781242
LiftableConstantExpressionHelpers.BuildClrCollectionAccessorLambda(navigation),
@@ -1193,9 +1257,9 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
11931257
QueryCompilationContext.QueryContextParameter,
11941258
_dataReaderParameter,
11951259
_resultCoordinatorParameter,
1196-
parentIdentifierLambda,
1197-
outerIdentifierLambda,
1198-
selfIdentifierLambda,
1260+
parentIdentifierLambdaCompiled,
1261+
outerIdentifierLambdaCompiled,
1262+
selfIdentifierLambdaCompiled,
11991263
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
12001264
relationalCollectionShaperExpression.ParentIdentifierValueComparers
12011265
.Select(x => (Func<object, object, bool>)x.Equals).ToArray(),
@@ -1265,6 +1329,14 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
12651329
QueryCompilationContext.QueryContextParameter,
12661330
_dataReaderParameter);
12671331

1332+
var parentIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1333+
parentIdentifierLambda.Compile(),
1334+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1335+
parentIdentifierLambda,
1336+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1337+
"parentIdentifierLambda",
1338+
typeof(Func<QueryContext, DbDataReader, object[]>));
1339+
12681340
_inline = false;
12691341

12701342
innerProcessor._inline = true;
@@ -1274,6 +1346,14 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
12741346
QueryCompilationContext.QueryContextParameter,
12751347
innerProcessor._dataReaderParameter);
12761348

1349+
var childIdentifierLambdaCompiled = _parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
1350+
childIdentifierLambda.Compile(),
1351+
Lambda<Func<MaterializerLiftableConstantContext, object>>(
1352+
childIdentifierLambda,
1353+
Parameter(typeof(MaterializerLiftableConstantContext), "_")),
1354+
"childIdentifierLambda",
1355+
typeof(Func<QueryContext, DbDataReader, object[]>));
1356+
12771357
innerProcessor._inline = false;
12781358

12791359
var collectionParameter = Parameter(collectionType);
@@ -1288,7 +1368,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
12881368
QueryCompilationContext.QueryContextParameter,
12891369
_dataReaderParameter,
12901370
_resultCoordinatorParameter,
1291-
parentIdentifierLambda,
1371+
parentIdentifierLambdaCompiled,
12921372
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
12931373
collectionAccessor,
12941374
LiftableConstantExpressionHelpers.BuildClrCollectionAccessorLambda(navigation),
@@ -1313,7 +1393,7 @@ when GetProjectionIndex(collectionResultExpression.ProjectionBindingExpression)
13131393
CreateReaderColumnsExpression(readerColumns, _parentVisitor.Dependencies.LiftableConstantFactory),
13141394
Constant(_detailedErrorsEnabled),
13151395
_resultCoordinatorParameter,
1316-
childIdentifierLambda,
1396+
childIdentifierLambdaCompiled,
13171397
_parentVisitor.Dependencies.LiftableConstantFactory.CreateLiftableConstant(
13181398
relationalSplitCollectionShaperExpression.IdentifierValueComparers
13191399
.Select(x => (Func<object, object, bool>)x.Equals).ToArray(),

0 commit comments

Comments
 (0)