Rusi Nova
Rusi Nova

Reputation: 2665

Is there any performance benefit in using const or readonly modifiers on fields in c#?

Is there any performance benefit to using const or readonly fields compared to regular, modifiable fields, when only using private variables.

For example:

public class FooBaar
{
     private string foo = "something";
     private const string baar = "something more"

     public void Baaz()
     {
         //access foo, access baar
     }
}

In the above example you can see there are two fields: foo and baar. Both are unaccessible outside the the class, so how come many people prefer to use const here, instead of just private. Does the const provide any performance benefit?


This question was previously closed by the community, because people misunderstood this question as "What is the difference between const and readonly in terms of performance?", which has been answered here: What is the difference between const and readonly?.
But what I actually mean is, "do I get any performance benefit by using const or readonly over not using any of them".

Upvotes: 12

Views: 9877

Answers (3)

Vagner Gon
Vagner Gon

Reputation: 645

I was wondering the same and I've use a tool to check the resulting IL output from the use of static and read-only modifiers.

Check this example:

public class C {

    const string test = "stuff";
    private static string test2 = "stuff2";

    public static void M() {
        System.Console.WriteLine(test);
        System.Console.WriteLine(test2);
    }
}

And the IL output for M():

 IL_0000: nop
 IL_0001: ldstr "stuff"
 IL_0006: call void [System.Console]System.Console::WriteLine(string)
 IL_000b: nop
 IL_000c: ldsfld string C::test2
 IL_0011: call void [System.Console]System.Console::WriteLine(string)
 IL_0016: nop
 IL_0017: ret

And a decompiled version:

section .data
test db 'stuff', 0
test2 db 'stuff2', 0

section .text
global _start

_start:
; Print test
mov rax, 1          ; syscall: write
mov rdi, 1          ; file descriptor: stdout
mov rsi, test       ; pointer to string
mov rdx, 6          ; length of string
syscall

; Print test2
mov rax, 1          ; syscall: write
mov rdi, 1          ; file descriptor: stdout
mov rsi, test2      ; pointer to string
mov rdx, 7          ; length of string
syscall

; Exit
mov rax, 60         ; syscall: exit
xor rdi, rdi        ; status: 0
syscall

It is unlikely that it will make any performance difference since both will become a pointer to a string.

Upvotes: 1

iandotkelly
iandotkelly

Reputation: 9134

A const will be optimized by the compiler to be inlined into your code, a readonly cannot be inlined. However you cannot make constants of all types - so here you must make them readonly.

So if you need a constant value in your code, you should first look to use a const if possible, if not then readonly is there to allow you to have the safety, but not the performance benefits.

As an example:

public class Example
{
    private const int foo = 5;
    private readonly Dictionary<int, string> bar = new Dictionary<int, string>();

    //.... missing stuff where bar is populated

    public void DoSomething()
    {
       Console.Writeline(bar[foo]);

       // when compiled the above line is replaced with Console.Writeline(bar[5]);
       // because at compile time the compiler can replace foo with 5
       // but it can't do anything inline with bar itself, as it is readonly
       // not a const, so cannot benefit from the optimization
    }
}

Upvotes: 29

spender
spender

Reputation: 120498

I wouldn't worry too much about the performance of these constructs until you encounter a critical piece of code that requires you to make such measurements. They're there to ensure correctness of code, not for performance reasons.

Upvotes: -3

Related Questions