Phase 16 of 30 · Topic 16.3

MethodInfo Invocation Overhead vs Compiled Expressions / Delegates

1Concept

Calling `MethodInfo.Invoke()` requires parameter array allocation (`object[]`), boxing, and security checks (~150ns). Compiling a `Delegate.CreateDelegate` or `Expression.Compile` reduces invocation overhead to ~1ns.

2Architecture Diagram

Direct Method Call:           0.3 ns (Native Speed)
Compiled Delegate / Emit:      1.2 ns (Near Native Speed)
MethodInfo.Invoke (Reflection): 150.0 ns (100x Slower + Heap Boxing Allocations!)

3Code Example

C# 13 & .NET 9
using System;
using System.Reflection;

public class TargetService
{
    public int Multiply(int a, int b) => a * b;
}

public class FastDelegateDemo
{
    public static void Main()
    {
        var instance = new TargetService();
        MethodInfo method = typeof(TargetService).GetMethod("Multiply")!;

        // Convert MethodInfo to strongly-typed fast delegate!
        var fastFunc = (Func<int, int, int>)Delegate.CreateDelegate(typeof(Func<int, int, int>), instance, method);

        int result = fastFunc(6, 7);
        Console.WriteLine($"Fast Delegate Invocation Result: {result} (Near Native Speed)");
    }
}

4Expected Output

Fast Delegate Invocation Result: 42 (Near Native Speed)

5Key Takeaways

  • Never call `MethodInfo.Invoke` repeatedly inside loops.
  • Use `Delegate.CreateDelegate` when the method signature is known at compile time.
  • Use `System.Linq.Expressions` or Source Generators when signatures vary dynamically.