Home > Blockchain >  In C#, why assign member variables to local variables and then use local variables instead of using
In C#, why assign member variables to local variables and then use local variables instead of using

Time:12-18

In C#, why assign member variables to local variables and then use local variables instead of using member variables directly, as shown in the following snippet:


internal class LocalVariableTest
{
    private readonly int[] _items = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };


    public void ConsoleWriteLine()
    {
        var items = _items;

        foreach (var item in items)
        {
            System.Console.WriteLine(item);
        }
    }

    public void ConsoleWriteLine2()
    {
        foreach (var item in _items)
        {
            System.Console.WriteLine(item);
        }
    }
}

What is the difference between ConsoleWriteLine and ConsoleWriteLine2?

I would like to know if there is any difference between the two methods after compiling. I have seen many places that have this way of writing. Which one has higher performance and where is the knowledge about this, such as Microsoft Learn?

CodePudding user response:

Any difference? barely.

The compiler should optimize it to be approximately the same.

Here, the difference in debug mode is two extra instructions and an additional variable on the stack. Will that be noticeable? Only way to know for sure is to run a benchmark with something like benchmark.net.

As pointed out in the comments, your code in release mode is identical.

You can view the difference with ILSpy, or an online equivalent like sharplab

// Methods
    .method public hidebysig 
        instance void ConsoleWriteLine () cil managed 
    {
        // Method begins at RVA 0x2094
        // Code size 39 (0x27)
        .maxstack 2
        .locals init (
            [0] int32[] items,
            [1] int32[],
            [2] int32,
            [3] int32 item
        )

        IL_0000: nop
        IL_0001: ldarg.0
        IL_0002: ldfld int32[] LocalVariableTest::_items
        IL_0007: stloc.0
        IL_0008: nop
        IL_0009: ldloc.0
        IL_000a: stloc.1
        IL_000b: ldc.i4.0
        IL_000c: stloc.2
        // sequence point: hidden
        IL_000d: br.s IL_0020
        // loop start (head: IL_0020)
            IL_000f: ldloc.1
            IL_0010: ldloc.2
            IL_0011: ldelem.i4
            IL_0012: stloc.3
            IL_0013: nop
            IL_0014: ldloc.3
            IL_0015: call void [System.Console]System.Console::WriteLine(int32)
            IL_001a: nop
            IL_001b: nop
            // sequence point: hidden
            IL_001c: ldloc.2
            IL_001d: ldc.i4.1
            IL_001e: add
            IL_001f: stloc.2

            IL_0020: ldloc.2
            IL_0021: ldloc.1
            IL_0022: ldlen
            IL_0023: conv.i4
            IL_0024: blt.s IL_000f
        // end loop

        IL_0026: ret
    } // end of method LocalVariableTest::ConsoleWriteLine

    .method public hidebysig 
        instance void ConsoleWriteLine2 () cil managed 
    {
        // Method begins at RVA 0x20c8
        // Code size 37 (0x25)
        .maxstack 2
        .locals init (
            [0] int32[],
            [1] int32,
            [2] int32 item
        )

        IL_0000: nop
        IL_0001: nop
        IL_0002: ldarg.0
        IL_0003: ldfld int32[] LocalVariableTest::_items
        IL_0008: stloc.0
        IL_0009: ldc.i4.0
        IL_000a: stloc.1
        // sequence point: hidden
        IL_000b: br.s IL_001e
        // loop start (head: IL_001e)
            IL_000d: ldloc.0
            IL_000e: ldloc.1
            IL_000f: ldelem.i4
            IL_0010: stloc.2
            IL_0011: nop
            IL_0012: ldloc.2
            IL_0013: call void [System.Console]System.Console::WriteLine(int32)
            IL_0018: nop
            IL_0019: nop
            // sequence point: hidden
            IL_001a: ldloc.1
            IL_001b: ldc.i4.1
            IL_001c: add
            IL_001d: stloc.1

            IL_001e: ldloc.1
            IL_001f: ldloc.0
            IL_0020: ldlen
            IL_0021: conv.i4
            IL_0022: blt.s IL_000d
        // end loop

        IL_0024: ret
    } // end of method LocalVariableTest::ConsoleWriteLine2
  • Related