C# Enum Performance

Performance optimization

Enums are fast. They are value types. We determine the effect an enum type has on performance in C# programs. Enums contain constant values. But how do these differ from regular const values?

Example

Enum

First, this program has an enum, three const ints, and three static readonly ints. We pass those values to another method, which will demonstrate how the values are loaded onto the evaluation stack in the intermediate language.

ConstReadonly
C# program that uses enum, const, and fields

using System;

enum Test
{
    Cat,
    Dog,
    Rabbit
}

class Program
{
    const int _cat = 0;
    const int _dog = 1;
    const int _rabbit = 2;

    static readonly int _cat2 = 0;
    static readonly int _dog2 = 1;
    static readonly int _rabbit2 = 2;

    static void Main()
    {
	Method(Test.Cat);
	Method(Test.Dog);
	Method(Test.Rabbit);

	Method(_cat);
	Method(_dog);
	Method(_rabbit);

	Method(_cat2);
	Method(_dog2);
	Method(_rabbit2);
    }

    static void Method(Test test)
    {
    }

    static void Method(int value)
    {
    }
}

Compiled Main method from program: IL

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    L_0000: ldc.i4.0
    L_0001: call void Program::Method(valuetype Test)
    L_0006: ldc.i4.1
    L_0007: call void Program::Method(valuetype Test)
    L_000c: ldc.i4.2
    L_000d: call void Program::Method(valuetype Test)
    L_0012: ldc.i4.0
    L_0013: call void Program::Method(int32)
    L_0018: ldc.i4.1
    L_0019: call void Program::Method(int32)
    L_001e: ldc.i4.2
    L_001f: call void Program::Method(int32)
    L_0024: ldsfld int32 Program::_cat2
    L_0029: call void Program::Method(int32)
    L_002e: ldsfld int32 Program::_dog2
    L_0033: call void Program::Method(int32)
    L_0038: ldsfld int32 Program::_rabbit2
    L_003d: call void Program::Method(int32)
    L_0042: ret
}

We see the Main() method in the IL.
To load enum values onto the stack,
it uses ldc.i4.0,
which loads a four byte zero. For const values, it also uses ldc.i4.0 to load zero. To load fields, it uses ldsfld.

ldsfld Instruction

Const values

Framework: NET

In the intermediate language, we see that enums are loaded in the same way as const values. They are embedded directly into the IL. Fields, on the other hand, require a field load instruction (ldsfld) which will impact performance.

Therefore:Enums are just as fast as const in typical usage. Fields are somewhat slower.

Summary

We looked at how enums are compiled in the IL of the .NET Framework. We demonstrated that the same instruction is used to load an enum value as is used to load a const value. On the other hand, fields use a different instruction.


C#: Enum