@@ -25,10 +25,15 @@ public override Expression Remap(int offset, Dictionary<Expression, Expression>
2525 return this ;
2626 }
2727
28- if ( processedExpressions . TryGetValue ( this , out var value ) ) {
29- return value ;
30- }
28+ return processedExpressions . TryGetValue ( this , out var value )
29+ ? value
30+ : RemapWithNoCheck ( offset , processedExpressions ) ;
31+ }
3132
33+ // Having this code as a separate method helps to avoid closure allocation during Remap call
34+ // in case processedExpressions dictionary already contains a result.
35+ private Expression RemapWithNoCheck ( int offset , Dictionary < Expression , Expression > processedExpressions )
36+ {
3237 var mapping = new Segment < int > ( Mapping . Offset + offset , Mapping . Length ) ;
3338
3439 FieldExpression Remap ( FieldExpression f ) => ( FieldExpression ) f . Remap ( offset , processedExpressions ) ;
@@ -72,12 +77,21 @@ public override Expression Remap(int[] map, Dictionary<Expression, Expression> p
7277 return result ;
7378 }
7479
75- public override Expression BindParameter ( ParameterExpression parameter , Dictionary < Expression , Expression > processedExpressions )
80+ public override Expression BindParameter (
81+ ParameterExpression parameter , Dictionary < Expression , Expression > processedExpressions )
7682 {
7783 if ( processedExpressions . TryGetValue ( this , out var value ) ) {
7884 return value ;
7985 }
8086
87+ return BindParameterWithNoCheck ( parameter , processedExpressions ) ;
88+ }
89+
90+ // Having this code as a separate method helps to avoid closure allocation during BindParameter call
91+ // in case processedExpressions dictionary already contains a result.
92+ private Expression BindParameterWithNoCheck (
93+ ParameterExpression parameter , Dictionary < Expression , Expression > processedExpressions )
94+ {
8195 FieldExpression BindParameter ( FieldExpression f )
8296 => ( FieldExpression ) f . BindParameter ( parameter , processedExpressions ) ;
8397
@@ -94,6 +108,13 @@ public override Expression RemoveOuterParameter(Dictionary<Expression, Expressio
94108 return value ;
95109 }
96110
111+ return RemoveOuterParameterWithNoCheck ( processedExpressions ) ;
112+ }
113+
114+ // Having this code as a separate method helps to avoid closure allocation during RemoveOuterParameter call
115+ // in case processedExpressions dictionary already contains a result.
116+ private Expression RemoveOuterParameterWithNoCheck ( Dictionary < Expression , Expression > processedExpressions )
117+ {
97118 FieldExpression RemoveOuterParameter ( FieldExpression f )
98119 => ( FieldExpression ) f . RemoveOuterParameter ( processedExpressions ) ;
99120
0 commit comments