Skip to content

Commit dcfa32f

Browse files
committed
adding the Constant without boxing and null constant with the less space
1 parent 57a62dd commit dcfa32f

File tree

4 files changed

+66
-34
lines changed

4 files changed

+66
-34
lines changed

src/FastExpressionCompiler.LightExpression/Expression.cs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,15 @@ private static ParameterExpression TryToMakeKnownTypeParameter(Type type, string
147147
: new TypedParameterExpression(type, name)
148148
};
149149

150-
public static readonly ConstantExpression NullConstant = new TypedConstantExpression<object>(null);
151-
public static readonly ConstantExpression FalseConstant = new TypedConstantExpression<bool>(false);
152-
public static readonly ConstantExpression TrueConstant = new TypedConstantExpression<bool>(true);
153-
public static readonly ConstantExpression ZeroConstant = new TypedConstantExpression<int>(0);
154-
public static readonly ConstantExpression OneConstant = new TypedConstantExpression<int>(1);
155-
public static readonly ConstantExpression MinusOneConstant = new TypedConstantExpression<int>(-1);
150+
public static readonly ConstantExpression NullConstant = new TypedNullConstantExpression<object>();
151+
public static readonly ConstantExpression FalseConstant = new ValueConstantExpression<bool>(false);
152+
public static readonly ConstantExpression TrueConstant = new ValueConstantExpression<bool>(true);
153+
public static readonly ConstantExpression ZeroConstant = new ValueConstantExpression<int>(0);
154+
public static readonly ConstantExpression OneConstant = new ValueConstantExpression<int>(1);
155+
public static readonly ConstantExpression MinusOneConstant = new ValueConstantExpression<int>(-1);
156156

157157
/// <summary>Avoids the boxing for all (two) bool values</summary>
158-
public static ConstantExpression Constant(bool value) =>
159-
value ? TrueConstant : FalseConstant;
158+
public static ConstantExpression Constant(bool value) => value ? TrueConstant : FalseConstant;
160159

161160
public static ConstantExpression Constant(object value)
162161
{
@@ -171,28 +170,28 @@ public static ConstantExpression Constant(object value)
171170
n == 0 ? ZeroConstant :
172171
n == 1 ? OneConstant :
173172
n == -1 ? MinusOneConstant :
174-
new TypedConstantExpression<int>(n);
173+
new ValueConstantExpression<int>(n);
175174

176-
return new ConstantExpression(value);
175+
return new ValueConstantExpression(value);
177176
}
178177

179-
// todo: @perf benchmark thw switch on the LightExprVsExpr_Create_ComplexExpr
178+
// todo: @perf benchmark the switch on the LightExprVsExpr_Create_ComplexExpr
180179
public static ConstantExpression Constant(object value, Type type)
181180
{
182181
if (value == null)
183182
{
184183
if (type == typeof(object))
185184
return NullConstant;
186-
return new TypedConstantExpression(null, type);
185+
return new TypedNullConstantExpression(type);
187186
}
188187

189188
if (type == typeof(bool))
190189
return (bool)value ? TrueConstant : FalseConstant;
191190

192191
if (type == value.GetType())
193-
return new ConstantExpression(value);
192+
return new ValueConstantExpression(value);
194193

195-
return new TypedConstantExpression(value, type);
194+
return new TypedValueConstantExpression(value, type);
196195
}
197196

198197
public static NewExpression New(Type type)
@@ -2288,12 +2287,11 @@ public sealed class TypedParameterExpression<T> : ParameterExpression
22882287
internal TypedParameterExpression(string name) : base(name) {}
22892288
}
22902289

2291-
public class ConstantExpression : Expression
2290+
// The basic constant with the null value
2291+
public abstract class ConstantExpression : Expression
22922292
{
22932293
public sealed override ExpressionType NodeType => ExpressionType.Constant;
2294-
public override Type Type => Value.GetType();
2295-
public readonly object Value; // todo: @perf convert to the property so I can delegate it to non-boxing version
2296-
internal ConstantExpression(object value) => Value = value;
2294+
public virtual object Value => null;
22972295
#if SUPPORTS_VISITOR
22982296
protected internal override Expression Accept(ExpressionVisitor visitor) => visitor.VisitConstant(this);
22992297
#endif
@@ -2303,25 +2301,44 @@ public class ConstantExpression : Expression
23032301
public override string ToString() => $"Constant({Value}, typeof({Type.ToCode()}))";
23042302
}
23052303

2306-
// todo: @perf @incomplete
2307-
// public sealed class ConstantValueExpression<T> : ConstantExpression where T : struct
2308-
// {
2309-
// public override Type Type => typeof(T)
2310-
// public readonly T ValueValue;
2304+
public sealed class TypedNullConstantExpression : ConstantExpression
2305+
{
2306+
public override Type Type { get; }
2307+
internal TypedNullConstantExpression(Type type) => Type = type;
2308+
}
2309+
2310+
public sealed class TypedNullConstantExpression<T> : ConstantExpression
2311+
{
2312+
public override Type Type => typeof(T);
2313+
}
2314+
2315+
public sealed class ValueConstantExpression : ConstantExpression
2316+
{
2317+
public override Type Type => Value.GetType();
2318+
public override object Value { get; }
2319+
internal ValueConstantExpression(object value) => Value = value;
2320+
}
23112321

2312-
// internal ConstantValueExpression(T value) => ValueValue = value;
2313-
// }
2322+
public sealed class ValueConstantExpression<T> : ConstantExpression
2323+
{
2324+
public override Type Type => typeof(T);
2325+
public override object Value { get; }
2326+
internal ValueConstantExpression(object value) => Value = value;
2327+
}
23142328

2315-
public sealed class TypedConstantExpression : ConstantExpression
2329+
public sealed class TypedValueConstantExpression : ConstantExpression
23162330
{
23172331
public override Type Type { get; }
2318-
internal TypedConstantExpression(object value, Type type) : base(value) => Type = type;
2332+
public override object Value { get; }
2333+
internal TypedValueConstantExpression(object value, Type type) { Value = value; Type = type; }
23192334
}
23202335

2321-
public sealed class TypedConstantExpression<T> : ConstantExpression
2336+
public sealed class TypedValueConstantExpression<T> : ConstantExpression where T : struct
23222337
{
23232338
public override Type Type => typeof(T);
2324-
internal TypedConstantExpression(object value) : base(value) { }
2339+
public override object Value => TypedValue;
2340+
public readonly T TypedValue;
2341+
internal TypedValueConstantExpression(T typedValue) => TypedValue = typedValue;
23252342
}
23262343

23272344
public class NewExpression : Expression, IArgumentProvider

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ THE SOFTWARE.
4343
#endif
4444
#if LIGHT_EXPRESSION
4545
using static FastExpressionCompiler.LightExpression.Expression;
46-
using PE = FastExpressionCompiler.LightExpression.ParameterExpression;
47-
namespace FastExpressionCompiler.LightExpression
46+
using PE = FastExpressionCompiler.LightExpression.ParameterExpression;
47+
namespace FastExpressionCompiler.LightExpression
4848
#else
4949
using static System.Linq.Expressions.Expression;
50-
using PE = System.Linq.Expressions.ParameterExpression;
50+
using PE = System.Linq.Expressions.ParameterExpression;
5151
namespace FastExpressionCompiler
5252
#endif
5353
{

test/FastExpressionCompiler.Benchmarks/LightExprVsExpr_CreateAndCompile_ComplexExpr.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@ public class LightExprVsExpr_CreateAndCompile_ComplexExpr
5353
| CreateExpression_and_CompileFast | 17.69 us | 0.350 us | 0.443 us | 1.31 | 0.04 | 1.8005 | 0.8850 | 0.0305 | 7.36 KB |
5454
| CreateLightExpression_and_CompileFast | 13.50 us | 0.152 us | 0.143 us | 1.00 | 0.00 | 1.5869 | 0.7935 | 0.0305 | 6.58 KB |
5555
56+
## v3.1
57+
58+
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042
59+
Intel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
60+
.NET Core SDK=5.0.202
61+
[Host] : .NET Core 5.0.5 (CoreCLR 5.0.521.16609, CoreFX 5.0.521.16609), X64 RyuJIT
62+
DefaultJob : .NET Core 5.0.5 (CoreCLR 5.0.521.16609, CoreFX 5.0.521.16609), X64 RyuJIT
63+
64+
65+
| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated |
66+
|-------------------------------------- |-----------:|----------:|----------:|------:|--------:|-------:|-------:|-------:|----------:|
67+
| CreateExpression_and_Compile | 185.081 us | 3.5893 us | 3.8406 us | 21.98 | 0.62 | 0.9766 | 0.4883 | - | 7.2 KB |
68+
| CreateExpression_and_CompileFast | 11.538 us | 0.2286 us | 0.6411 us | 1.41 | 0.10 | 1.0223 | 0.5035 | 0.0458 | 6.28 KB |
69+
| CreateLightExpression_and_CompileFast | 8.408 us | 0.1501 us | 0.1844 us | 1.00 | 0.00 | 0.8850 | 0.4425 | 0.0458 | 5.47 KB |
70+
5671
*/
5772

5873
[Benchmark]

test/FastExpressionCompiler.Benchmarks/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public static void Main()
2727
// BenchmarkRunner.Run<NestedLambdasVsVars>();
2828

2929
// BenchmarkRunner.Run<AutoMapper_UseCase_Simplified_OneProperty.Compile_only>();
30-
BenchmarkRunner.Run<AutoMapper_UseCase_Simplified_OneProperty.Create_and_Compile>();
30+
// BenchmarkRunner.Run<AutoMapper_UseCase_Simplified_OneProperty.Create_and_Compile>();
3131
// BenchmarkRunner.Run<AutoMapper_UseCase_Simplified_OneProperty.Invoke_compiled_delegate>();
3232

3333
//BenchmarkRunner.Run<NestedLambdaOverhead>();
@@ -52,7 +52,7 @@ public static void Main()
5252
// BenchmarkRunner.Run<Deserialize_Simple>();
5353

5454
// BenchmarkRunner.Run<LightExprVsExpr_Create_ComplexExpr>();
55-
// BenchmarkRunner.Run<LightExprVsExpr_CreateAndCompile_ComplexExpr>();
55+
BenchmarkRunner.Run<LightExprVsExpr_CreateAndCompile_ComplexExpr>();
5656

5757
//BenchmarkRunner.Run<LightExprVsExpr_CreateAndCompile_NestedLambdaExpr>();
5858
// BenchmarkRunner.Run<LightExprVsExpr_CreateAndCompile_SimpleExpr>();

0 commit comments

Comments
 (0)