Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# goto语句是否影响c中的性能#_C#_Performance_Memory Management_Coding Style_Goto - Fatal编程技术网

C# goto语句是否影响c中的性能#

C# goto语句是否影响c中的性能#,c#,performance,memory-management,coding-style,goto,C#,Performance,Memory Management,Coding Style,Goto,在c代码中使用GOTO语句,而不是使用loop或多个单独的用户定义函数,是否会对性能产生影响 我不确定,但是GOTO语句可能会发生内存跳转,并且会影响性能。不,不会 在不知道备选方案是什么的情况下,很难回答“它会影响绩效吗”,但我将制作一个样本: using System; public class C { public void M() { var x = 7; switch(x) // START SWITCH {

c
代码中使用
GOTO
语句,而不是使用
loop
或多个单独的用户定义
函数,是否会对性能产生影响

我不确定,但是
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 default 2.9.0)会产生以下IL(即Java语言的字节码):

.class私有自动ansi“”
{
}//下课
.class公共自动ansi BEFOREFILDInit C
扩展[mscorlib]System.Object
{
//方法
.方法公共隐藏
实例void M()cil托管
{
//方法从RVA 0x2050开始
//代码大小99(0x63)
.maxstack 2
.init(
[0]int32
)
IL_0000:ldc.i4.7
IL_0001:stloc.0
//起动开关
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
ILU 000a:br.s ILU 0024
IL_000c:ldstr“你好”
IL_0011:调用void[mscorlib]System.Console::WriteLine(字符串)
IL_0016:br.s IL_002e
IL_0018:ldstr“世界”
IL_001d:调用void[mscorlib]System.Console::WriteLine(字符串)
ILU 0022:br.s ILU 002e
IL_0024:ldstr“呃…”
IL_0029:调用void[mscorlib]System.Console::WriteLine(字符串)
//终端开关
//开始转到
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“呃…”
IL_003b:调用void[mscorlib]System.Console::WriteLine(字符串)
ILU 0040:br.s ILU 0058
ILU 0042:ldstr“你好”
IL_0047:调用void[mscorlib]System.Console::WriteLine(字符串)
IL_004c:br.s IL_0058
ILU 004e:ldstr“世界”
IL_0053:调用void[mscorlib]System.Console::WriteLine(字符串)
//结束后藤
IL_0058:ldstr“完成”
IL_005d:调用void[mscorlib]System.Console::WriteLine(字符串)
IL_0062:ret
}//方法C::M的结尾
.method公共隐藏显示特殊名称rtspecialname
实例void.ctor()cil托管
{
//方法从RVA 0x20bf开始
//代码大小7(0x7)
.maxstack 8
IL_0000:ldarg.0
IL_0001:调用实例void[mscorlib]System.Object::.ctor()
IL_0006:ret
}//方法C的结尾::.ctor
}//C类结束
切换表单有3个
beq
和1个
br.s
,转到表单有2个
beq
和2个
br.s
,不同的是它们是相同的。
br.s
的成本大概小于或等于
beq
的成本,因此转到方法的成本不大于切换方法的成本


最后,使用goto是个坏主意。如果您想争论这个事实,请在另一个问题上这样做:

性能影响与否,它会破坏您的可维护性。永远不要使用
GOTO
s,除非你陷入了一个没有任何选择的真正特定的小问题。当你尝试使用
GOTO
时,你发现了什么性能差异?你确实试过了,对吗?我不像Pierre Luc那样相信,简单地使用
goto
意味着破坏您的可维护性。当然,这是一种强制性的方法来编写fall-through
case
块。另一方面,对于流量控制,一个
goto
确实留下了很多需要改进的地方,而且几乎总是可以避免的。所以你也可以;即使可维护性没有被一个
goto
破坏,它肯定会有点污点。:)@PeterDuniho方法用于增强可读性。经典的
for
循环易于识别和阅读
GOTO
s只会制造一个巨大的混乱,完全违背了OOP的基本原则、SRP,并且会在阻止任何可测试性的同时使圈复杂度急剧上升。我敢说,你可以尝试在完全相同的时间内理解一个带有gotos的5k行方法,而不是一个干净的结构化OOP架构。老实说,如果你想对循环和方法等东西进行微优化(当然是毫无益处的),那就直接进行组装吧。@Pierre Luccinoult:谁说了五千行的方法?让我休息一下……仅仅因为
goto
语句可能是代码的一部分,否则也很糟糕,没有理由相信代码中的一个
goto
语句会毁掉代码。@Peter他谈到使用goto而不是方法。如果程序生成5k行,这意味着您有一个5k行的单一方法。我们这里说的不是一个goto(即使已经够危险了),而是用em替换所有的循环。
.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