Do you want to invoke action million times? Delegates are slow - they cannot be inlined. Not inlined methods have a call overhead - jumps and reduntant data movement. Sure, you can just inline manually or replace delegates with methods, but there are a lot of boilerplate code.
However there are a trick. C# dynamic methods allow to generate IL code at runtime. You can emit call instruction using MethodInfo which will be inlined by compiler (or not - it’s depends on size of method and compiler settings).
Dynamic methods
Instance Action
Let’s create method to call Action<int>
First, create instance:
Second, obtain IlGenerator:
And finally, emit IL code:
Let’s invoke our dynamic method:
Static Action
If you have an error in previous section, that’s probably because you used static methods.
All anonymous methods are instance (even if they have static modifier), but local functions and normal methods can be static.
You can check it using original.Method.IsStatic.
To call static method, you don’t need instance, so remove second argument:
Loops
Methods above are not so efficient - you just create another delegate that call’s method. If you want to invoke original delegate in a loop efficiently - emit a loop in DynamicMethod.
You can write required code and use Rider IL viewer to view il code you need to emit
The required code for for (int i = 0; i < end; i++) {} will be:
So, our loop method will be:
Batches
Check instruction support before execution! Many processors doesn't support all of the instruction sets
JIT compiler doesn’t vectorize code (like c++), but you can manually vectorize code using System.Runtime.Intrinsics: