@@ -26,17 +26,14 @@ namespace Xtensive.Orm.Linq.Materialization
2626 [ Serializable ]
2727 internal class ExpressionMaterializer : PersistentExpressionVisitor
2828 {
29- private static readonly MethodInfo BuildPersistentTupleMethod ;
30- private static readonly MethodInfo GetTupleSegmentMethod ;
31- private static readonly MethodInfo GetParameterValueMethod ;
32- private static readonly PropertyInfo ParameterContextProperty ;
33- private static readonly MethodInfo GetTupleParameterValueMethod ;
29+ private static readonly MethodInfo BuildPersistentTupleMethod = typeof ( ExpressionMaterializer ) . GetMethod ( nameof ( BuildPersistentTuple ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
30+ private static readonly MethodInfo GetTupleSegmentMethod = typeof ( ExpressionMaterializer ) . GetMethod ( nameof ( GetTupleSegment ) , BindingFlags . NonPublic | BindingFlags . Static ) ;
31+ private static readonly MethodInfo GetParameterValueMethod = WellKnownOrmTypes . ParameterContext . GetMethod ( nameof ( ParameterContext . GetValue ) ) ;
32+ private static readonly PropertyInfo ParameterContextProperty = WellKnownOrmTypes . ItemMaterializationContext . GetProperty ( nameof ( ItemMaterializationContext . ParameterContext ) ) ;
33+ private static readonly MethodInfo GetTupleParameterValueMethod = GetParameterValueMethod . MakeGenericMethod ( WellKnownOrmTypes . Tuple ) ;
3434
35- private readonly TranslatorContext context ;
36- private readonly ParameterExpression tupleParameter ;
37- private readonly ParameterExpression itemMaterializationContextParameter ;
38- private readonly Dictionary < IEntityExpression , int > entityRegistry = new Dictionary < IEntityExpression , int > ( ) ;
39- private readonly HashSet < Parameter < Tuple > > tupleParameters ;
35+ private static readonly ParameterExpression MaterializationContextParameter = Expression . Parameter ( WellKnownOrmTypes . ItemMaterializationContext , "mc" ) ;
36+ private static readonly ConstantExpression TypeReferenceAccuracyConstantExpression = Expression . Constant ( TypeReferenceAccuracy . BaseType ) ;
4037
4138 private static readonly Type [ ] SubQueryConstructorArgumentTypes = {
4239 WellKnownOrmTypes . ProjectionExpression ,
@@ -46,23 +43,35 @@ internal class ExpressionMaterializer : PersistentExpressionVisitor
4643 WellKnownOrmTypes . ItemMaterializationContext
4744 } ;
4845
46+ private static readonly Type [ ] GroupingConstructorArgumentTypesTemplate = new [ ] {
47+ WellKnownOrmTypes . ProjectionExpression ,
48+ WellKnownOrmTypes . TranslatedQuery ,
49+ WellKnownOrmTypes . ParameterOfTuple ,
50+ WellKnownOrmTypes . Tuple ,
51+ null ,
52+ WellKnownOrmTypes . ItemMaterializationContext
53+ } ;
54+
55+ private readonly TranslatorContext context ;
56+ private readonly ParameterExpression tupleParameter ;
57+ private readonly ParameterExpression itemMaterializationContextParameter ;
58+ private readonly Dictionary < IEntityExpression , int > entityRegistry = new Dictionary < IEntityExpression , int > ( ) ;
59+ private readonly HashSet < Parameter < Tuple > > tupleParameters ;
60+
4961 #region Public static methods
5062
5163 public static LambdaExpression MakeLambda ( Expression expression , TranslatorContext context )
5264 {
53- var tupleParameter = Expression . Parameter ( WellKnownOrmTypes . Tuple , "tuple" ) ;
54- var visitor = new ExpressionMaterializer ( tupleParameter , context , null , EnumerableUtils < Parameter < Tuple > > . Empty ) ;
65+ var visitor = new ExpressionMaterializer ( QueryHelper . TupleParameter , context , null , EnumerableUtils < Parameter < Tuple > > . Empty ) ;
5566 var processedExpression = OwnerRemover . RemoveOwner ( expression ) ;
56- return FastExpression . Lambda ( visitor . Visit ( processedExpression ) , tupleParameter ) ;
67+ return FastExpression . Lambda ( visitor . Visit ( processedExpression ) , QueryHelper . TupleParameter ) ;
5768 }
5869
5970 public static MaterializationInfo MakeMaterialization ( ItemProjectorExpression projector , TranslatorContext context ,
6071 IEnumerable < Parameter < Tuple > > tupleParameters )
6172 {
62- var tupleParameter = Expression . Parameter ( WellKnownOrmTypes . Tuple , "tuple" ) ;
63- var materializationContextParameter = Expression . Parameter ( WellKnownOrmTypes . ItemMaterializationContext , "mc" ) ;
64- var visitor = new ExpressionMaterializer ( tupleParameter , context , materializationContextParameter , tupleParameters ) ;
65- var lambda = FastExpression . Lambda ( visitor . Visit ( projector . Item ) , tupleParameter , materializationContextParameter ) ;
73+ var visitor = new ExpressionMaterializer ( QueryHelper . TupleParameter , context , MaterializationContextParameter , tupleParameters ) ;
74+ var lambda = FastExpression . Lambda ( visitor . Visit ( projector . Item ) , QueryHelper . TupleParameter , MaterializationContextParameter ) ;
6675 var count = visitor . entityRegistry . Count ;
6776 return new MaterializationInfo ( count , lambda ) ;
6877 }
@@ -110,16 +119,14 @@ protected override Expression VisitGroupingExpression(GroupingExpression groupin
110119 // 2. Create constructor
111120 var keyType = groupingExpression . KeyExpression . Type ;
112121 var keyMaterializer = Visit ( groupingExpression . KeyExpression ) ;
122+ // Copying from template is 2x+ faster than instantiating an array with defined items
123+ var ctorParameterTypes = new Type [ GroupingConstructorArgumentTypesTemplate . Length ] ;
124+ Array . Copy ( GroupingConstructorArgumentTypesTemplate , ctorParameterTypes , GroupingConstructorArgumentTypesTemplate . Length ) ;
125+ ctorParameterTypes [ 4 ] = keyType ;
126+
113127 var groupingCtor = WellKnownOrmTypes . GroupingOfTKeyTElement
114128 . MakeGenericType ( keyType , elementType )
115- . GetConstructor ( new [ ] {
116- WellKnownOrmTypes . ProjectionExpression ,
117- WellKnownOrmTypes . TranslatedQuery ,
118- WellKnownOrmTypes . ParameterOfTuple ,
119- WellKnownOrmTypes . Tuple ,
120- keyType ,
121- WellKnownOrmTypes . ItemMaterializationContext
122- } ) ;
129+ . GetConstructor ( ctorParameterTypes ) ;
123130
124131 // 3. Create result expression.
125132 var resultExpression = Expression . New (
@@ -321,7 +328,7 @@ protected override Expression VisitKeyExpression(KeyExpression expression)
321328 Expression . Field ( itemMaterializationContextParameter , ItemMaterializationContext . SessionFieldInfo ) ,
322329 WellKnownMembers . SessionNodeId ) ,
323330 Expression . Constant ( expression . EntityType ) ,
324- Expression . Constant ( TypeReferenceAccuracy . BaseType ) ,
331+ TypeReferenceAccuracyConstantExpression ,
325332 tupleExpression ) ;
326333 }
327334
0 commit comments