.NET
reflection
performance
duplicate
programming

What is the cost of .NET reflection?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Reflection in .NET is expensive compared with direct, statically compiled access, but the real question is where that cost shows up. One-time metadata inspection is often acceptable, while repeated reflective invocation inside hot loops can become a genuine performance problem.

What Reflection Actually Costs

Reflection does work the runtime cannot optimize as aggressively as normal code:

  • metadata lookup
  • name-based member discovery
  • argument boxing and unboxing in some cases
  • runtime access checks
  • indirect invocation through APIs such as MethodInfo.Invoke

That means this kind of code is much slower than a direct call:

csharp
var method = typeof(MyService).GetMethod("Run");
method.Invoke(serviceInstance, null);

The most expensive part is usually repeated dynamic invocation, not simply obtaining a Type once.

Cheap Enough Versus Too Expensive

Reflection is usually fine when:

  • scanning assemblies at startup
  • loading plugins occasionally
  • building serializers or mappers once and caching the result

Reflection becomes risky when:

  • used per request in a hot path
  • used per item in a large loop
  • used repeatedly to discover the same members without caching

That is why many frameworks use reflection only during setup, then compile delegates or cache metadata for steady-state execution.

Example Benchmark Shape

csharp
1using System;
2using System.Diagnostics;
3using System.Reflection;
4
5class Demo
6{
7    public int AddOne(int x) => x + 1;
8
9    static void Main()
10    {
11        var demo = new Demo();
12        var method = typeof(Demo).GetMethod(nameof(AddOne));
13
14        var sw = Stopwatch.StartNew();
15        for (int i = 0; i < 1_000_000; i++)
16        {
17            demo.AddOne(i);
18        }
19        sw.Stop();
20        Console.WriteLine($"Direct: {sw.ElapsedMilliseconds} ms");
21
22        sw.Restart();
23        for (int i = 0; i < 1_000_000; i++)
24        {
25            method!.Invoke(demo, new object[] { i });
26        }
27        sw.Stop();
28        Console.WriteLine($"Reflection: {sw.ElapsedMilliseconds} ms");
29    }
30}

The exact numbers depend on machine and runtime, but the reflective loop will be dramatically slower. That does not mean reflection is "bad." It means you should avoid paying that price repeatedly when the member information is stable.

The Standard Mitigation: Cache and Compile

If you must discover members dynamically, do it once and cache the result. For frequent invocation, create a delegate when possible:

csharp
1var method = typeof(Demo).GetMethod(nameof(Demo.AddOne));
2var del = (Func<Demo, int, int>)Delegate.CreateDelegate(
3    typeof(Func<Demo, int, int>),
4    method!);
5
6int result = del(new Demo(), 5);

This keeps the flexible discovery step while avoiding repeated MethodInfo.Invoke overhead.

The same idea applies to property access and constructor activation. If a dynamic path is used frequently, move the expensive reflective discovery to startup or first use, then keep a cached executable path for steady-state calls.

Reflection Cost Is Not Only Speed

There is also a maintainability cost:

  • compile-time checks are weaker
  • errors shift to runtime
  • code is harder to follow

So even if performance is acceptable, reflective code should still justify its complexity.

Common Pitfalls

The biggest mistake is benchmarking reflection once, seeing it is slower, and concluding it must never be used. Startup-time or rarely executed reflection is often perfectly reasonable.

Another mistake is doing repeated GetProperty, GetMethod, or Invoke calls inside tight loops without caching.

A third issue is using reflection when generics, interfaces, or delegates would solve the problem more simply and safely.

Summary

  • Reflection is slower than direct code, especially for repeated invocation.
  • One-time metadata discovery is often acceptable.
  • Hot-path MethodInfo.Invoke and repeated lookup are where the cost becomes significant.
  • Cache metadata and prefer compiled delegates when dynamic invocation is frequent.
  • The cost of reflection includes maintainability and runtime error risk, not just CPU time.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.