@@ -24,6 +24,16 @@ public class Invoke
24
24
private static MethodInfo s_method_nullableInt ;
25
25
private static ConstructorInfo s_ctor_int_string_struct_class ;
26
26
private static ConstructorInfo s_ctor_NoParams ;
27
+
28
+ #if NET8_0_OR_GREATER
29
+ private static MethodInvoker s_method_invoker ;
30
+ private static MethodInvoker s_method_int_string_struct_class_invoker ;
31
+ private static MethodInvoker s_method_byref_int_string_struct_class_invoker ;
32
+ private static MethodInvoker s_method_byref_int_string_struct_class_bool_invoker ;
33
+ private static ConstructorInvoker s_ctor_int_string_struct_class_invoker ;
34
+ private static ConstructorInvoker s_ctor_NoParams_invoker ;
35
+ #endif
36
+
27
37
private static PropertyInfo s_property_int ;
28
38
private static PropertyInfo s_property_class ;
29
39
private static FieldInfo s_field_int ;
@@ -86,6 +96,15 @@ public void Setup()
86
96
87
97
s_staticField_struct = typeof ( MyClass ) .
88
98
GetField ( nameof ( MyClass . s_blittableStruct ) ) ;
99
+
100
+ #if NET8_0_OR_GREATER
101
+ s_method_invoker = MethodInvoker . Create ( s_method ) ;
102
+ s_method_int_string_struct_class_invoker = MethodInvoker . Create ( s_method_int_string_struct_class ) ;
103
+ s_method_byref_int_string_struct_class_invoker = MethodInvoker . Create ( s_method_byref_int_string_struct_class ) ;
104
+ s_method_byref_int_string_struct_class_bool_invoker = MethodInvoker . Create ( s_method_byref_int_string_struct_class_bool ) ;
105
+ s_ctor_int_string_struct_class_invoker = ConstructorInvoker . Create ( s_ctor_int_string_struct_class ) ;
106
+ s_ctor_NoParams_invoker = ConstructorInvoker . Create ( typeof ( MyClass ) . GetConstructor ( Array . Empty < Type > ( ) ) ) ;
107
+ #endif
89
108
}
90
109
91
110
public static void Method_int_string_struct_class ( int i , string s , MyBlittableStruct myStruct , MyClass myClass )
@@ -122,6 +141,18 @@ public void Method0_NoParms()
122
141
}
123
142
}
124
143
144
+
145
+ #if NET8_0_OR_GREATER
146
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
147
+ public void Method0_NoParms_MethodInvoker ( )
148
+ {
149
+ for ( int i = 0 ; i < Iterations ; i ++ )
150
+ {
151
+ s_method_invoker . Invoke ( s_MyClass ) ;
152
+ }
153
+ }
154
+ #endif
155
+
125
156
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
126
157
// Include the array allocation and population for a typical scenario.
127
158
public void StaticMethod4_arrayNotCached_int_string_struct_class ( )
@@ -154,6 +185,32 @@ public void StaticMethod4_int_string_struct_class()
154
185
}
155
186
}
156
187
188
+ #if NET8_0_OR_GREATER
189
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
190
+ public void StaticMethod4_int_string_struct_class_MethodInvoker ( )
191
+ {
192
+ // To make the test more comparable to the MethodBase tests, set up the references and pre-boxed types.
193
+ object boxedInt = s_args4 [ 0 ] ;
194
+ object stringRef = s_args4 [ 1 ] ;
195
+ object boxedStruct = s_args4 [ 2 ] ;
196
+ object myClassRef = s_args4 [ 3 ] ;
197
+
198
+ for ( int i = 0 ; i < Iterations ; i ++ )
199
+ {
200
+ s_method_int_string_struct_class_invoker . Invoke ( null , boxedInt , stringRef , boxedStruct , myClassRef ) ;
201
+ }
202
+ }
203
+
204
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
205
+ public void StaticMethod4_int_string_struct_class_MethodInvokerWithSpan ( )
206
+ {
207
+ for ( int i = 0 ; i < Iterations ; i ++ )
208
+ {
209
+ s_method_int_string_struct_class_invoker . Invoke ( null , new Span < object > ( s_args4 ) ) ;
210
+ }
211
+ }
212
+ #endif
213
+
157
214
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
158
215
public void StaticMethod4_ByRefParams_int_string_struct_class ( )
159
216
{
@@ -163,6 +220,23 @@ public void StaticMethod4_ByRefParams_int_string_struct_class()
163
220
}
164
221
}
165
222
223
+ #if NET8_0_OR_GREATER
224
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
225
+ public void StaticMethod4_ByRefParams_int_string_struct_class_MethodInvoker ( )
226
+ {
227
+ // To make the test more comparable to the MethodBase tests, set up the references and pre-boxed types.
228
+ object boxedInt = s_args4 [ 0 ] ;
229
+ object stringRef = s_args4 [ 1 ] ;
230
+ object boxedStruct = s_args4 [ 2 ] ;
231
+ object myClassRef = s_args4 [ 3 ] ;
232
+
233
+ for ( int i = 0 ; i < Iterations ; i ++ )
234
+ {
235
+ s_method_byref_int_string_struct_class_invoker . Invoke ( null , boxedInt , stringRef , boxedStruct , myClassRef ) ;
236
+ }
237
+ }
238
+ #endif
239
+
166
240
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
167
241
// Starting with 5 parameters, stack allocations are replaced with heap allocations.
168
242
public void StaticMethod5_ByRefParams_int_string_struct_class_bool ( )
@@ -173,6 +247,17 @@ public void StaticMethod5_ByRefParams_int_string_struct_class_bool()
173
247
}
174
248
}
175
249
250
+ #if NET8_0_OR_GREATER
251
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
252
+ public void StaticMethod5_ByRefParams_int_string_struct_class_bool_MethodInvoker ( )
253
+ {
254
+ for ( int i = 0 ; i < Iterations ; i ++ )
255
+ {
256
+ s_method_byref_int_string_struct_class_bool_invoker . Invoke ( null , new Span < object > ( s_args5 ) ) ;
257
+ }
258
+ }
259
+ #endif
260
+
176
261
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
177
262
public void Ctor0_NoParams ( )
178
263
{
@@ -182,6 +267,31 @@ public void Ctor0_NoParams()
182
267
}
183
268
}
184
269
270
+ #if NET8_0_OR_GREATER
271
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
272
+ public void Ctor0_NoParams_ConstructorInvoker ( )
273
+ {
274
+ for ( int i = 0 ; i < Iterations ; i ++ )
275
+ {
276
+ s_ctor_NoParams_invoker . Invoke ( ) ;
277
+ }
278
+ }
279
+ #endif
280
+
281
+ /// <summary>
282
+ /// Reinvoke the constructor on the same object. Used by some serializers.
283
+ /// </summary>
284
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
285
+ public void Ctor0_NoParams_Reinvoke ( )
286
+ {
287
+ MyClass obj = new MyClass ( ) ;
288
+
289
+ for ( int i = 0 ; i < Iterations ; i ++ )
290
+ {
291
+ s_ctor_NoParams . Invoke ( obj , null ) ;
292
+ }
293
+ }
294
+
185
295
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
186
296
public void Ctor0_ActivatorCreateInstance_NoParams ( )
187
297
{
@@ -200,6 +310,23 @@ public void Ctor4_int_string_struct_class()
200
310
}
201
311
}
202
312
313
+ #if NET8_0_OR_GREATER
314
+ [ Benchmark ( OperationsPerInvoke = Iterations ) ]
315
+ public void Ctor4_int_string_struct_class_ConstructorInvoker ( )
316
+ {
317
+ // To make the test more comparable to the MethodBase tests, set up the references and pre-boxed types.
318
+ object boxedInt = s_args4 [ 0 ] ;
319
+ object stringRef = s_args4 [ 1 ] ;
320
+ object boxedStruct = s_args4 [ 2 ] ;
321
+ object myClassRef = s_args4 [ 3 ] ;
322
+
323
+ for ( int i = 0 ; i < Iterations ; i ++ )
324
+ {
325
+ s_ctor_int_string_struct_class_invoker . Invoke ( boxedInt , stringRef , boxedStruct , myClassRef ) ;
326
+ }
327
+ }
328
+ #endif
329
+
203
330
[ Benchmark ( OperationsPerInvoke = Iterations ) ]
204
331
public void Ctor4_ActivatorCreateInstance ( )
205
332
{
0 commit comments