簡體   English   中英

goto語句會影響C#的性能嗎

[英]does goto statement impact performance in c#

c#代碼中使用GOTO語句是否會對性能產生影響,而不是使用loop或多個單獨的用戶定義functions

我不確定,但是GOTO語句可能會發生內存跳躍,並會影響性能。

不,不是。

在不知道替代方案是什么的情況下,很難回答“是否會影響性能”,但我將組成一個示例:

using System;
public class C {
    public void M() {
        var x = 7;
        switch(x) // START SWITCH
        {
            case 1:
                Console.WriteLine("Hello");
                break;
            case 2:
                Console.WriteLine("World");
                break;
            default:
                Console.WriteLine("Uh...");
                break;
        }
        // END SWITCH
        // START GOTO
        if (x == 1)
        {
            goto Hello;
        }
        else if (x == 2)
        {
            goto World;
        }
        Console.WriteLine("Uh...");
        goto End;
    Hello:
        Console.WriteLine("Hello");
        goto End;
    World:
        Console.WriteLine("World");
    End:
        // END GOTO
        Console.WriteLine("Done");
    }
}

在發布模式下使用C#進行編譯(使用sharplab.io默認值為2.9.0),將產生以下IL(即,適用於Java的字節碼):

.class private auto ansi '<Module>'
{
} // end of class <Module>

.class public auto ansi beforefieldinit C
    extends [mscorlib]System.Object
{
    // Methods
    .method public hidebysig 
        instance void M () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 99 (0x63)
        .maxstack 2
        .locals init (
            [0] int32
        )

        IL_0000: ldc.i4.7
        IL_0001: stloc.0
        // START SWITCH
        IL_0002: ldloc.0
        IL_0003: ldc.i4.1
        IL_0004: beq.s IL_000c

        IL_0006: ldloc.0
        IL_0007: ldc.i4.2
        IL_0008: beq.s IL_0018

        IL_000a: br.s IL_0024

        IL_000c: ldstr "Hello"
        IL_0011: call void [mscorlib]System.Console::WriteLine(string)
        IL_0016: br.s IL_002e

        IL_0018: ldstr "World"
        IL_001d: call void [mscorlib]System.Console::WriteLine(string)
        IL_0022: br.s IL_002e

        IL_0024: ldstr "Uh..."
        IL_0029: call void [mscorlib]System.Console::WriteLine(string)
        // END SWITCH
        // START GOTO
        IL_002e: ldloc.0
        IL_002f: ldc.i4.1
        IL_0030: beq.s IL_0042

        IL_0032: ldloc.0
        IL_0033: ldc.i4.2
        IL_0034: beq.s IL_004e

        IL_0036: ldstr "Uh..."
        IL_003b: call void [mscorlib]System.Console::WriteLine(string)
        IL_0040: br.s IL_0058

        IL_0042: ldstr "Hello"
        IL_0047: call void [mscorlib]System.Console::WriteLine(string)
        IL_004c: br.s IL_0058

        IL_004e: ldstr "World"
        IL_0053: call void [mscorlib]System.Console::WriteLine(string)
        // END GOTO
        IL_0058: ldstr "Done"
        IL_005d: call void [mscorlib]System.Console::WriteLine(string)
        IL_0062: ret
    } // end of method C::M

    .method public hidebysig specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x20bf
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method C::.ctor

} // end of class C

交換形式具有3 beq和1 br.s ,而goto形式具有2 beq和2 br.s ,除了它們相同。 br.s的成本大概小於或等於beq的成本,因此goto方法的成本不大於switch方法的成本。

最后,使用goto是一個壞主意。 如果您想就這一事實爭論不休,請針對這樣一個不同的問題: 使用goto有什么問題?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM