Skip to content

Commit 8aa8eaa

Browse files
committed
optimizing memory of Expression of T;
optimizing for the custom MethodCallExpression
1 parent 228f03e commit 8aa8eaa

File tree

1 file changed

+49
-40
lines changed

1 file changed

+49
-40
lines changed

src/FastExpressionCompiler.LightExpression/Expression.cs

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,14 @@ public static NewExpression New(ConstructorInfo ctor,
254254

255255
public static MethodCallExpression Call(MethodInfo method, params Expression[] arguments) =>
256256
arguments == null || arguments.Length == 0
257-
? new MethodCallExpression(method)
257+
? new NotNullMethodCallExpression(method)
258258
: new ManyArgumentsMethodCallExpression(method, arguments);
259259

260260
public static MethodCallExpression Call(MethodInfo method, IEnumerable<Expression> arguments)
261261
{
262262
var args = arguments.AsReadOnlyList();
263263
if (args == null || args.Count == 0)
264-
return new MethodCallExpression(method);
264+
return new NotNullMethodCallExpression(method);
265265
return new ManyArgumentsMethodCallExpression(method, args);
266266
}
267267

@@ -284,7 +284,7 @@ public static MethodCallExpression Call(Type type, string methodName, Type[] typ
284284
{
285285
var method = type.FindMethodOrThrow(methodName, typeArguments, arguments, TypeTools.StaticMethods);
286286
if (arguments == null || arguments.Length == 0)
287-
return new MethodCallExpression(method);
287+
return new NotNullMethodCallExpression(method);
288288
return new ManyArgumentsMethodCallExpression(method, arguments);
289289
}
290290

@@ -293,7 +293,7 @@ public static MethodCallExpression Call(Type type, string methodName, Type[] typ
293293
var argExprs = arguments.AsReadOnlyList();
294294
var method = type.FindMethodOrThrow(methodName, typeArguments, argExprs, TypeTools.StaticMethods);
295295
if (argExprs == null || argExprs.Count == 0)
296-
return new MethodCallExpression(method);
296+
return new NotNullMethodCallExpression(method);
297297
return new ManyArgumentsMethodCallExpression(method, argExprs);
298298
}
299299

@@ -315,11 +315,11 @@ public static MethodCallExpression Call(Expression instance, string methodName,
315315
}
316316

317317
public static MethodCallExpression Call(MethodInfo method) =>
318-
new MethodCallExpression(method);
318+
new NotNullMethodCallExpression(method);
319319

320320
public static MethodCallExpression Call(Expression instance, MethodInfo method) =>
321321
instance == null
322-
? new MethodCallExpression(method)
322+
? new NotNullMethodCallExpression(method)
323323
: new InstanceMethodCallExpression(instance, method);
324324

325325
public static MethodCallExpression Call(MethodInfo method, Expression argument) =>
@@ -588,7 +588,7 @@ public static UnaryExpression Unbox(Expression expression, Type type)
588588
}
589589

590590
public static LambdaExpression Lambda(Expression body) =>
591-
new LambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
591+
new TypedLambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
592592

593593
public static LambdaExpression Lambda(Type delegateType, Expression body)
594594
{
@@ -597,7 +597,7 @@ public static LambdaExpression Lambda(Type delegateType, Expression body)
597597

598598
var returnType = GetDelegateReturnType(delegateType);
599599
if (returnType == body.Type)
600-
return new LambdaExpression(delegateType, body);
600+
return new TypedLambdaExpression(delegateType, body);
601601
return new TypedReturnLambdaExpression(delegateType, body, returnType);
602602
}
603603

@@ -606,14 +606,14 @@ public static LambdaExpression Lambda(Type delegateType, Expression body, Type r
606606
if (delegateType == null || delegateType == typeof(Delegate))
607607
delegateType = Tools.GetFuncOrActionType(returnType);
608608
if (returnType == body.Type)
609-
return new LambdaExpression(delegateType, body);
609+
return new TypedLambdaExpression(delegateType, body);
610610
return new TypedReturnLambdaExpression(delegateType, body, returnType);
611611
}
612612

613613
public static LambdaExpression Lambda(Expression body, IReadOnlyList<ParameterExpression> parameters) =>
614614
parameters?.Count > 0
615615
? new ManyParametersLambdaExpression(Tools.GetFuncOrActionType(Tools.GetParamTypes(parameters), body.Type), body, parameters)
616-
: new LambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
616+
: new TypedLambdaExpression(Tools.GetFuncOrActionType(body.Type), body);
617617

618618
public static LambdaExpression Lambda(Expression body, params ParameterExpression[] parameters) =>
619619
Lambda(body, (IReadOnlyList<ParameterExpression>)parameters);
@@ -675,7 +675,7 @@ public static LambdaExpression Lambda(Type delegateType, Expression body, IReadO
675675
return new TypedReturnManyParametersLambdaExpression(delegateType, body, parameters, returnType);
676676
}
677677
if (returnType == body.Type)
678-
return new LambdaExpression(delegateType, body);
678+
return new TypedLambdaExpression(delegateType, body);
679679
return new TypedReturnLambdaExpression(delegateType, body, returnType);
680680
}
681681

@@ -2615,34 +2615,40 @@ public sealed class OneBoundNewArrayBoundsExpression : NewArrayExpression
26152615
public override IReadOnlyList<Expression> Expressions => new[] { Bound };
26162616
public override int ArgumentCount => 1;
26172617
public override Expression GetArgument(int i) => Bound;
2618-
internal OneBoundNewArrayBoundsExpression(Type arrayType, Expression bound) : base(arrayType) => Bound = bound;
2618+
internal OneBoundNewArrayBoundsExpression(Type arrayType, Expression bound) : base(arrayType) =>
2619+
Bound = bound;
26192620
}
26202621

26212622
public class MethodCallExpression : Expression, IArgumentProvider
26222623
{
26232624
public sealed override ExpressionType NodeType => ExpressionType.Call;
26242625
public override Type Type => Method.ReturnType;
2625-
public readonly MethodInfo Method;
2626+
public virtual MethodInfo Method => null;
26262627
public virtual Expression Object => null;
26272628
public virtual IReadOnlyList<Expression> Arguments => Tools.Empty<Expression>();
26282629
public virtual int ArgumentCount => 0;
26292630
public virtual Expression GetArgument(int i) => throw new NotImplementedException();
2630-
internal MethodCallExpression(MethodInfo method) => Method = method;
26312631
#if SUPPORTS_VISITOR
26322632
protected internal override Expression Accept(ExpressionVisitor visitor) => visitor.VisitMethodCall(this);
26332633
#endif
26342634
internal override SysExpr CreateSysExpression(ref LiveCountArray<LightAndSysExpr> exprsConverted) =>
26352635
SysExpr.Call(Object?.ToExpression(ref exprsConverted), Method, ToExpressions(Arguments, ref exprsConverted));
26362636
}
26372637

2638-
public sealed class InstanceMethodCallExpression : MethodCallExpression
2638+
public class NotNullMethodCallExpression : MethodCallExpression
2639+
{
2640+
public override MethodInfo Method { get; }
2641+
internal NotNullMethodCallExpression(MethodInfo method) => Method = method;
2642+
}
2643+
2644+
public sealed class InstanceMethodCallExpression : NotNullMethodCallExpression
26392645
{
26402646
public override Expression Object { get; }
26412647
internal InstanceMethodCallExpression(Expression instance, MethodInfo method) : base(method) =>
26422648
Object = instance;
26432649
}
26442650

2645-
public class ManyArgumentsMethodCallExpression : MethodCallExpression
2651+
public class ManyArgumentsMethodCallExpression : NotNullMethodCallExpression
26462652
{
26472653
private readonly IReadOnlyList<Expression> _arguments;
26482654
public sealed override IReadOnlyList<Expression> Arguments => _arguments;
@@ -2660,7 +2666,7 @@ internal InstanceManyArgumentsMethodCallExpression(Expression instance, MethodIn
26602666
: base(method, arguments) => Object = instance;
26612667
}
26622668

2663-
public class OneArgumentMethodCallExpression : MethodCallExpression
2669+
public class OneArgumentMethodCallExpression : NotNullMethodCallExpression
26642670
{
26652671
public override IReadOnlyList<Expression> Arguments => new[] { Argument };
26662672
public readonly Expression Argument;
@@ -2677,7 +2683,7 @@ internal InstanceOneArgumentMethodCallExpression(Expression instance, MethodInfo
26772683
: base(method, argument) => Object = instance;
26782684
}
26792685

2680-
public class TwoArgumentsMethodCallExpression : MethodCallExpression
2686+
public class TwoArgumentsMethodCallExpression : NotNullMethodCallExpression
26812687
{
26822688
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1 };
26832689
public readonly Expression Argument0, Argument1;
@@ -2697,7 +2703,7 @@ internal InstanceTwoArgumentsMethodCallExpression(Expression instance, MethodInf
26972703
Expression argument0, Expression argument1) : base(method, argument0, argument1) => Object = instance;
26982704
}
26992705

2700-
public class ThreeArgumentsMethodCallExpression : MethodCallExpression
2706+
public class ThreeArgumentsMethodCallExpression : NotNullMethodCallExpression
27012707
{
27022708
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1, Argument2 };
27032709
public readonly Expression Argument0, Argument1, Argument2;
@@ -2718,7 +2724,7 @@ internal InstanceThreeArgumentsMethodCallExpression(Expression instance, MethodI
27182724
Expression a0, Expression a1, Expression a2) : base(method, a0, a1, a2) => Object = instance;
27192725
}
27202726

2721-
public class FourArgumentsMethodCallExpression : MethodCallExpression
2727+
public class FourArgumentsMethodCallExpression : NotNullMethodCallExpression
27222728
{
27232729
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1, Argument2, Argument3 };
27242730
public readonly Expression Argument0, Argument1, Argument2, Argument3;
@@ -2741,7 +2747,7 @@ internal InstanceFourArgumentsMethodCallExpression(Expression instance, MethodIn
27412747
: base(method, argument0, argument1, argument2, argument3) => Object = instance;
27422748
}
27432749

2744-
public class FiveArgumentsMethodCallExpression : MethodCallExpression
2750+
public class FiveArgumentsMethodCallExpression : NotNullMethodCallExpression
27452751
{
27462752
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1, Argument2, Argument3, Argument4 };
27472753
public readonly Expression Argument0, Argument1, Argument2, Argument3, Argument4;
@@ -2763,7 +2769,7 @@ internal InstanceFiveArgumentsMethodCallExpression(Expression instance, MethodIn
27632769
: base(method, a0, a1, a2, a3, a4) => Object = instance;
27642770
}
27652771

2766-
public class SixArgumentsMethodCallExpression : MethodCallExpression
2772+
public class SixArgumentsMethodCallExpression : NotNullMethodCallExpression
27672773
{
27682774
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1, Argument2, Argument3, Argument4, Argument5 };
27692775
public readonly Expression Argument0, Argument1, Argument2, Argument3, Argument4, Argument5;
@@ -2785,7 +2791,7 @@ internal InstanceSixArgumentsMethodCallExpression(Expression instance, MethodInf
27852791
: base(method, a0, a1, a2, a3, a4, a5) => Object = instance;
27862792
}
27872793

2788-
public class SevenArgumentsMethodCallExpression : MethodCallExpression
2794+
public class SevenArgumentsMethodCallExpression : NotNullMethodCallExpression
27892795
{
27902796
public override IReadOnlyList<Expression> Arguments => new[] { Argument0, Argument1, Argument2, Argument3, Argument4, Argument5, Argument6 };
27912797
public readonly Expression Argument0, Argument1, Argument2, Argument3, Argument4, Argument5, Argument6;
@@ -3543,20 +3549,16 @@ public WithComparisonSwitchExpression(Type type, Expression switchValue, Express
35433549
: base(type, switchValue, defaultBody, cases) => Comparison = comparison;
35443550
}
35453551

3546-
public class LambdaExpression : Expression, IParameterProvider
3552+
public abstract class LambdaExpression : Expression, IParameterProvider
35473553
{
35483554
public sealed override ExpressionType NodeType => ExpressionType.Lambda;
3549-
public override Type Type { get; }
35503555
public readonly Expression Body;
35513556
public virtual Type ReturnType => Body.Type;
35523557
public virtual IReadOnlyList<ParameterExpression> Parameters => Tools.Empty<ParameterExpression>();
35533558
public virtual int ParameterCount => 0;
3554-
public virtual ParameterExpression GetParameter(int index) => throw new NotImplementedException("Requested the parameter from the no-parameter lambda");
3555-
internal LambdaExpression(Type delegateType, Expression body)
3556-
{
3557-
Type = delegateType;
3558-
Body = body;
3559-
}
3559+
public virtual ParameterExpression GetParameter(int index) =>
3560+
throw new NotImplementedException("Requested the parameter from the no-parameter lambda");
3561+
protected LambdaExpression(Expression body) => Body = body;
35603562
#if SUPPORTS_VISITOR
35613563
protected internal override Expression Accept(ExpressionVisitor visitor) => visitor.VisitLambda(this);
35623564
#endif
@@ -3567,7 +3569,13 @@ internal override SysExpr CreateSysExpression(ref LiveCountArray<LightAndSysExpr
35673569
SysExpr.Lambda(Type, Body.ToExpression(ref exprsConverted), ParameterExpression.ToParameterExpressions(Parameters, ref exprsConverted));
35683570
}
35693571

3570-
public class OneParameterLambdaExpression : LambdaExpression
3572+
public class TypedLambdaExpression : LambdaExpression
3573+
{
3574+
public sealed override Type Type { get; }
3575+
internal TypedLambdaExpression(Type delegateType, Expression body) : base(body) => Type = delegateType;
3576+
}
3577+
3578+
public class OneParameterLambdaExpression : TypedLambdaExpression
35713579
{
35723580
public readonly ParameterExpression Parameter0;
35733581
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0 };
@@ -3577,7 +3585,7 @@ internal OneParameterLambdaExpression(Type delegateType, Expression body, Parame
35773585
Parameter0 = parameter;
35783586
}
35793587

3580-
public class TwoParametersLambdaExpression : LambdaExpression
3588+
public class TwoParametersLambdaExpression : TypedLambdaExpression
35813589
{
35823590
public readonly ParameterExpression Parameter0, Parameter1;
35833591
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0, Parameter1 };
@@ -3590,7 +3598,7 @@ internal TwoParametersLambdaExpression(Type delegateType, Expression body,
35903598
}
35913599
}
35923600

3593-
public class ThreeParametersLambdaExpression : LambdaExpression
3601+
public class ThreeParametersLambdaExpression : TypedLambdaExpression
35943602
{
35953603
public readonly ParameterExpression Parameter0, Parameter1, Parameter2;
35963604
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0, Parameter1, Parameter2 };
@@ -3603,7 +3611,7 @@ internal ThreeParametersLambdaExpression(Type delegateType, Expression body,
36033611
}
36043612
}
36053613

3606-
public class FourParametersLambdaExpression : LambdaExpression
3614+
public class FourParametersLambdaExpression : TypedLambdaExpression
36073615
{
36083616
public readonly ParameterExpression Parameter0, Parameter1, Parameter2, Parameter3;
36093617
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0, Parameter1, Parameter2, Parameter3 };
@@ -3617,7 +3625,7 @@ internal FourParametersLambdaExpression(Type delegateType, Expression body,
36173625
}
36183626
}
36193627

3620-
public class FiveParametersLambdaExpression : LambdaExpression
3628+
public class FiveParametersLambdaExpression : TypedLambdaExpression
36213629
{
36223630
public readonly ParameterExpression Parameter0, Parameter1, Parameter2, Parameter3, Parameter4;
36233631
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0, Parameter1, Parameter2, Parameter3, Parameter4 };
@@ -3632,7 +3640,7 @@ internal FiveParametersLambdaExpression(Type delegateType, Expression body,
36323640
}
36333641
}
36343642

3635-
public class SixParametersLambdaExpression : LambdaExpression
3643+
public class SixParametersLambdaExpression : TypedLambdaExpression
36363644
{
36373645
public readonly ParameterExpression Parameter0, Parameter1, Parameter2, Parameter3, Parameter4, Parameter5;
36383646
public sealed override IReadOnlyList<ParameterExpression> Parameters => new[] { Parameter0, Parameter1, Parameter2, Parameter3, Parameter4, Parameter5 };
@@ -3647,7 +3655,7 @@ internal SixParametersLambdaExpression(Type delegateType, Expression body,
36473655
}
36483656
}
36493657

3650-
public class ManyParametersLambdaExpression : LambdaExpression
3658+
public class ManyParametersLambdaExpression : TypedLambdaExpression
36513659
{
36523660
private readonly IReadOnlyList<ParameterExpression> _parameters;
36533661
public sealed override IReadOnlyList<ParameterExpression> Parameters => _parameters;
@@ -3657,7 +3665,7 @@ internal ManyParametersLambdaExpression(Type delegateType, Expression body, IRea
36573665
: base(delegateType, body) => _parameters = parameters;
36583666
}
36593667

3660-
public sealed class TypedReturnLambdaExpression : LambdaExpression
3668+
public sealed class TypedReturnLambdaExpression : TypedLambdaExpression
36613669
{
36623670
public override Type ReturnType { get; }
36633671
internal TypedReturnLambdaExpression(Type delegateType, Expression body, Type returnType) : base(delegateType, body) =>
@@ -3722,7 +3730,8 @@ internal TypedReturnManyParametersLambdaExpression(Type delegateType, Expression
37223730

37233731
public class Expression<TDelegate> : LambdaExpression where TDelegate : System.Delegate
37243732
{
3725-
internal Expression(Expression body) : base(typeof(TDelegate), body) { }
3733+
public sealed override Type Type => typeof(TDelegate);
3734+
internal Expression(Expression body) : base(body) { }
37263735
#if SUPPORTS_VISITOR
37273736
protected internal override Expression Accept(ExpressionVisitor visitor) => visitor.VisitLambda(this);
37283737
#endif

0 commit comments

Comments
 (0)