Skip to content

TrustJIT_MyEmitDelegate

wuke32767 edited this page Mar 21, 2025 · 8 revisions

Come on, tell me.

What do you desire?

The called methods is complicated.

// this is some random expression.
var ax = 8 * c;
var dx = e + f;
var bx = f - b + 3;
var cx = d + e;
var fx = a * a - g;
var ex = d + c + e + g;
var gx = b - d * a;
return ax * bx - cx % dx == gx - ex - bx ? fx + cx * dx : ax + gx - 4;

All methods is ILHooked.

Standard will call the method delegate. ILHook loads an extra reference.

StandardStatic will call the static version of the method. ILHook do nothing. this is (should be) CelesteTAS EmitStaticDelegate.

Standard2 will call the method. ILHook loads an extra reference.

Official is the official EmitDelegate.

MineStatic is to test what i found. it's a new way to emit delegate. (store all existing stack values to local variables, ldnull, load them back, and trust jit)

Mine is the delegate variant of MineStatic, to test what if the delegate can't be static.


BenchmarkDotNet v0.14.0, Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 9.0.202
  [Host]     : .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2
  DefaultJob : .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2


Method Mean Error StdDev Median
Padding 0.0013 ns 0.0021 ns 0.0019 ns 0.0004 ns
Standard 32.8116 ns 0.0717 ns 0.0671 ns 32.8074 ns
StandardStatic 20.4179 ns 0.0308 ns 0.0288 ns 20.4153 ns
Standard2 31.7824 ns 0.0339 ns 0.0301 ns 31.7789 ns
Official 33.3374 ns 0.0443 ns 0.0370 ns 33.3310 ns
Mine 32.3552 ns 0.0240 ns 0.0200 ns 32.3579 ns
MineStatic 22.0780 ns 0.0299 ns 0.0265 ns 22.0757 ns

// * Detailed results *

TrustJIT_MyEmitDelegate.Padding: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 0.001 ns, StdErr = 0.001 ns (38.92%), N = 15, StdDev = 0.002 ns

Min = 0.000 ns, Q1 = 0.000 ns, Median = 0.000 ns, Q3 = 0.002 ns, Max = 0.006 ns

IQR = 0.002 ns, LowerFence = -0.002 ns, UpperFence = 0.004 ns

ConfidenceInterval = [-0.001 ns; 0.003 ns] (CI 99.9%), Margin = 0.002 ns (161.13% of Mean)

Skewness = 1.17, Kurtosis = 2.7, MValue = 2.2

-------------------- Histogram --------------------

[-0.001 ns ; 0.001 ns) | @@@@@@@@@@@

[ 0.001 ns ; 0.004 ns) | @

[ 0.004 ns ; 0.006 ns) | @@@


TrustJIT_MyEmitDelegate.Standard: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 32.812 ns, StdErr = 0.017 ns (0.05%), N = 15, StdDev = 0.067 ns

Min = 32.687 ns, Q1 = 32.763 ns, Median = 32.807 ns, Q3 = 32.865 ns, Max = 32.925 ns

IQR = 0.102 ns, LowerFence = 32.609 ns, UpperFence = 33.018 ns

ConfidenceInterval = [32.740 ns; 32.883 ns] (CI 99.9%), Margin = 0.072 ns (0.22% of Mean)

Skewness = 0.04, Kurtosis = 1.86, MValue = 2

-------------------- Histogram --------------------

[32.651 ns ; 32.960 ns) | @@@@@@@@@@@@@@@


TrustJIT_MyEmitDelegate.StandardStatic: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 20.418 ns, StdErr = 0.007 ns (0.04%), N = 15, StdDev = 0.029 ns

Min = 20.381 ns, Q1 = 20.396 ns, Median = 20.415 ns, Q3 = 20.435 ns, Max = 20.479 ns

IQR = 0.038 ns, LowerFence = 20.339 ns, UpperFence = 20.492 ns

ConfidenceInterval = [20.387 ns; 20.449 ns] (CI 99.9%), Margin = 0.031 ns (0.15% of Mean)

Skewness = 0.53, Kurtosis = 2.17, MValue = 2

-------------------- Histogram --------------------

[20.366 ns ; 20.495 ns) | @@@@@@@@@@@@@@@


TrustJIT_MyEmitDelegate.Standard2: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 31.782 ns, StdErr = 0.008 ns (0.03%), N = 14, StdDev = 0.030 ns

Min = 31.740 ns, Q1 = 31.762 ns, Median = 31.779 ns, Q3 = 31.801 ns, Max = 31.850 ns

IQR = 0.039 ns, LowerFence = 31.704 ns, UpperFence = 31.860 ns

ConfidenceInterval = [31.749 ns; 31.816 ns] (CI 99.9%), Margin = 0.034 ns (0.11% of Mean)

Skewness = 0.58, Kurtosis = 2.52, MValue = 2

-------------------- Histogram --------------------

[31.724 ns ; 31.867 ns) | @@@@@@@@@@@@@@


TrustJIT_MyEmitDelegate.Official: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 33.337 ns, StdErr = 0.010 ns (0.03%), N = 13, StdDev = 0.037 ns

Min = 33.271 ns, Q1 = 33.315 ns, Median = 33.331 ns, Q3 = 33.366 ns, Max = 33.395 ns

IQR = 0.051 ns, LowerFence = 33.239 ns, UpperFence = 33.442 ns

ConfidenceInterval = [33.293 ns; 33.382 ns] (CI 99.9%), Margin = 0.044 ns (0.13% of Mean)

Skewness = -0.11, Kurtosis = 1.82, MValue = 2

-------------------- Histogram --------------------

[33.251 ns ; 33.416 ns) | @@@@@@@@@@@@@


TrustJIT_MyEmitDelegate.Mine: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 32.355 ns, StdErr = 0.006 ns (0.02%), N = 13, StdDev = 0.020 ns

Min = 32.300 ns, Q1 = 32.353 ns, Median = 32.358 ns, Q3 = 32.366 ns, Max = 32.379 ns

IQR = 0.013 ns, LowerFence = 32.333 ns, UpperFence = 32.386 ns

ConfidenceInterval = [32.331 ns; 32.379 ns] (CI 99.9%), Margin = 0.024 ns (0.07% of Mean)

Skewness = -1.46, Kurtosis = 4.88, MValue = 2

-------------------- Histogram --------------------

[32.288 ns ; 32.391 ns) | @@@@@@@@@@@@@


TrustJIT_MyEmitDelegate.MineStatic: DefaultJob

Runtime = .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2; GC = Concurrent Workstation

Mean = 22.078 ns, StdErr = 0.007 ns (0.03%), N = 14, StdDev = 0.026 ns

Min = 22.039 ns, Q1 = 22.061 ns, Median = 22.076 ns, Q3 = 22.084 ns, Max = 22.130 ns

IQR = 0.023 ns, LowerFence = 22.027 ns, UpperFence = 22.117 ns

ConfidenceInterval = [22.048 ns; 22.108 ns] (CI 99.9%), Margin = 0.030 ns (0.14% of Mean)

Skewness = 0.72, Kurtosis = 2.53, MValue = 2

-------------------- Histogram --------------------

[22.024 ns ; 22.145 ns) | @@@@@@@@@@@@@@


// * Summary *

BenchmarkDotNet v0.14.0, Ubuntu 24.04.2 LTS (Noble Numbat)

AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores

.NET SDK 9.0.202

[Host] : .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2

DefaultJob : .NET 9.0.3 (9.0.325.11113), X64 RyuJIT AVX2

| Method | Mean | Error | StdDev | Median |

|--------------- |-----------:|----------:|----------:|-----------:|

| Padding | 0.0013 ns | 0.0021 ns | 0.0019 ns | 0.0004 ns |

| Standard | 32.8116 ns | 0.0717 ns | 0.0671 ns | 32.8074 ns |

| StandardStatic | 20.4179 ns | 0.0308 ns | 0.0288 ns | 20.4153 ns |

| Standard2 | 31.7824 ns | 0.0339 ns | 0.0301 ns | 31.7789 ns |

| Official | 33.3374 ns | 0.0443 ns | 0.0370 ns | 33.3310 ns |

| Mine | 32.3552 ns | 0.0240 ns | 0.0200 ns | 32.3579 ns |

| MineStatic | 22.0780 ns | 0.0299 ns | 0.0265 ns | 22.0757 ns |

// * Warnings *

ZeroMeasurement

TrustJIT_MyEmitDelegate.Padding: Default -> The method duration is indistinguishable from the empty method duration

// * Hints *

Outliers

TrustJIT_MyEmitDelegate.Standard2: Default -> 1 outlier was removed (34.85 ns)

TrustJIT_MyEmitDelegate.Official: Default -> 2 outliers were removed (35.21 ns, 35.21 ns)

TrustJIT_MyEmitDelegate.Mine: Default -> 2 outliers were removed, 3 outliers were detected (33.97 ns, 34.07 ns, 34.13 ns)

TrustJIT_MyEmitDelegate.MineStatic: Default -> 1 outlier was removed (23.86 ns)

// * Legends *

Mean : Arithmetic mean of all measurements

Error : Half of 99.9% confidence interval

StdDev : Standard deviation of all measurements

Median : Value separating the higher half of all measurements (50th percentile)

1 ns : 1 Nanosecond (0.000000001 sec)

Clone this wiki locally