Skip to content

Commit f92f5cb

Browse files
committed
#475 reusing the whole ILGenerator with the m_scope tokens and m_ILStream; exposing more of the FEC IL gen stuff
1 parent 53c1d20 commit f92f5cb

File tree

3 files changed

+361
-16
lines changed

3 files changed

+361
-16
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,7 @@ public static bool TryEmit(Expression expr,
23332333

23342334
case ExpressionType.Default:
23352335
if (exprType != typeof(void) && (parent & ParentFlags.IgnoreResult) == 0)
2336-
EmitDefault(exprType, il);
2336+
EmitDefault(il, exprType);
23372337
return true;
23382338

23392339
case ExpressionType.Index:
@@ -2690,7 +2690,8 @@ private static bool TryEmitCoalesceOperator(BinaryExpression expr, IReadOnlyList
26902690
return il.EmitPopIfIgnoreResult(parent);
26912691
}
26922692

2693-
private static void EmitDefault(Type type, ILGenerator il)
2693+
/// <summary>Emit default op code for the type</summary>
2694+
public static void EmitDefault(ILGenerator il, Type type)
26942695
{
26952696
if (type.IsClass)
26962697
{
@@ -6216,8 +6217,9 @@ private static void EmitLoadLocalVariableAddress(ILGenerator il, int location)
62166217
il.Demit(OpCodes.Ldloca, (short)location);
62176218
}
62186219

6220+
/// <summary>Load local variable on stack</summary>
62196221
[MethodImpl((MethodImplOptions)256)]
6220-
internal static bool EmitLoadLocalVariable(ILGenerator il, int location)
6222+
public static bool EmitLoadLocalVariable(ILGenerator il, int location)
62216223
{
62226224
if (location == 0)
62236225
il.Demit(OpCodes.Ldloc_0);
@@ -6267,8 +6269,9 @@ private static int EmitStoreLocalVariable(ILGenerator il, Type type)
62676269
return location;
62686270
}
62696271

6272+
/// <summary>Stores and loads the variable</summary>
62706273
[MethodImpl((MethodImplOptions)256)]
6271-
internal static void EmitStoreAndLoadLocalVariable(ILGenerator il, int location)
6274+
public static void EmitStoreAndLoadLocalVariable(ILGenerator il, int location)
62726275
{
62736276
if (location == 0)
62746277
{
@@ -6302,7 +6305,8 @@ internal static void EmitStoreAndLoadLocalVariable(ILGenerator il, int location)
63026305
}
63036306
}
63046307

6305-
internal static int EmitStoreAndLoadLocalVariable(ILGenerator il, Type t)
6308+
/// <summary>Stores and loads the variable, and returns it</summary>
6309+
public static int EmitStoreAndLoadLocalVariable(ILGenerator il, Type t)
63066310
{
63076311
var location = il.GetNextLocalVarIndex(t);
63086312
EmitStoreAndLoadLocalVariable(il, location);
@@ -8150,7 +8154,7 @@ public static T GetFirst<T>(this IEnumerable<T> source)
81508154
}
81518155

81528156
[RequiresUnreferencedCode(Trimming.Message)]
8153-
internal static class ILGeneratorTools
8157+
public static class ILGeneratorTools
81548158
{
81558159
#if DEMIT
81568160
[MethodImpl((MethodImplOptions)256)]

test/FastExpressionCompiler.Benchmarks/Issue468_Compile_vs_FastCompile.cs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,17 +287,37 @@ public object CompiledFast()
287287
public class Issue475_ReuseVsNoReuse
288288
{
289289
/*
290-
290+
## Baseline
291+
292+
BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3915)
293+
Intel Core i9-8950HK CPU 2.90GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
294+
.NET SDK 9.0.203
295+
[Host] : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX2
296+
DefaultJob : .NET 9.0.4 (9.0.425.16305), X64 RyuJIT AVX2
297+
298+
299+
| Method | Mean | Error | StdDev | Ratio | RatioSD | Rank | Gen0 | Gen1 | Allocated | Alloc Ratio |
300+
|------------------- |---------:|----------:|----------:|------:|--------:|-----:|-------:|-------:|----------:|------------:|
301+
| ReuseILGenerator | 5.317 us | 0.1028 us | 0.1441 us | 0.95 | 0.04 | 1 | 0.3510 | 0.3433 | 2.16 KB | 0.94 |
302+
| NoReuseILGenerator | 5.602 us | 0.1085 us | 0.1590 us | 1.00 | 0.04 | 1 | 0.3738 | 0.3586 | 2.3 KB | 1.00 |
303+
304+
## Reusing the whole ILGenerator with the m_scope tokens and m_ILStream
305+
306+
| Method | Mean | Error | StdDev | Ratio | RatioSD | Rank | Gen0 | Gen1 | Allocated | Alloc Ratio |
307+
|------------------- |---------:|----------:|----------:|------:|--------:|-----:|-------:|-------:|----------:|------------:|
308+
| ReuseILGenerator | 4.531 us | 0.0898 us | 0.1451 us | 0.87 | 0.04 | 1 | 0.2747 | 0.2670 | 1.71 KB | 0.74 |
309+
| NoReuseILGenerator | 5.211 us | 0.1025 us | 0.1874 us | 1.00 | 0.05 | 2 | 0.3738 | 0.3586 | 2.3 KB | 1.00 |
310+
291311
*/
292312
[Benchmark(Baseline = true)]
293-
public object NoReuse()
313+
public object NoReuseILGenerator()
294314
{
295-
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.NoReuse();
315+
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.NoReuseILGenerator();
296316
}
297317

298318
[Benchmark]
299-
public object Reuse()
319+
public object ReuseILGenerator()
300320
{
301-
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.Reuse();
321+
return IssueTests.Issue475_Reuse_DynamicMethod_if_possible.ReuseILGenerator();
302322
}
303323
}

0 commit comments

Comments
 (0)