简体   繁体   English

Goto语句在C#中运行缓慢吗?

[英]Is the goto statement slow in c#?

I'm working on a C# .NET application that uses some rather complex scientific formulas on large sets of data (10 million data points on average). 我正在研究一个C#.NET应用程序,该应用程序对大型数据集(平均1000万个数据点)使用一些相当复杂的科学公式。 Part of what I am doing requires optimizing the formula implementations as best as possible. 我正在做的部分工作要求尽可能优化公式的实现。

I noticed that one formula implementation uses goto, and that made me wonder: is goto slower than other flow control constructs? 我注意到一个公式实现使用goto,这让我感到奇怪:goto是否比其他流控制构造慢?

is goto slower than other flow control constructs? goto比其他流控制构造慢吗?

No. All the other flow control constructs are basically goto anyway. 不会。其他所有流控制构造基本上都是goto

The goto instruction in C# is no slower than any other control flow construct. C#中的goto指令不比任何其他控制流构造慢。 In fact the vast majority of control flow constructs (if, while, for, etc ...) is implemented in terms of goto . 实际上,绝大多数控制流构造(如果,则、、等)都是根据goto

For example: 例如:

if (someExpr) { 
  Console.WriteLine("here");
}
Console.WriteLine("there");

Is essentially compiled down to the following 基本上编译为以下内容

gotoIf !someExpr theLabel;
Console.WriteLine("here");
theLabel:
Console.WriteLine("there");

I noticed that one formula implementation uses goto, and that made me wonder: is goto slower than other flow control constructs? 我注意到一个公式实现使用goto,这让我感到奇怪:goto是否比其他流控制构造慢?

goto will not be any slower than any other flow control mechanism. goto速度不会比任何其他流控制机制慢。 It, like most flow control mechanisms get compiled into a br.s (or similar) MSIL instruction. 像大多数流控制机制一样,它被编译成一个br.s (或类似的)MSIL指令。 However, there are some situations where goto can be slightly faster. 但是,在某些情况下goto可能会稍快一些。 They are mostly limited to situations involving the use of break and continue inside nested loops. 它们主要限于涉及使用break和在嵌套循环内continue Consider the following code. 考虑下面的代码。

bool condition = false;
for (int i = 0; i < BigNumber; i++)
{
    for (int j = 0; j < i; j++)
    {
        for (int k = 0; k < j; k++)
        {
            condition = Evaluate(i, j, k);
            if (condition)
            {
              // break out of everything
            }
        }
    }
}

There are different ways you could you break out of the entire thing. 您可以通过多种方式来突破整个问题。 Here is one method. 这是一种方法。

bool condition = false;
for (int i = 0; i < BigNumber; i++)
{
    for (int j = 0; j < i; j++)
    {
        for (int k = 0; k < j; k++)
        {
            condition = Evaluate(i, j, k);
            if (condition) break;
        }
        if (condition) break;
    }
    if (condition) break;
}

The problem is that each loop must check the condition flag. 问题在于每个循环都必须检查condition标志。 We could refactor this with a goto to make it slightly more efficient and a bit more elegant to boot. 我们可以使用goto对其进行重构,以使其效率更高一些,启动起来也更优雅一些。

for (int i = 0; i < BigNumber; i++)
{
    for (int j = 0; j < i; j++)
    {
        for (int k = 0; k < j; k++)
        {
            if (Evaluate(i, j, k)) goto BAILOUT;
        }
    }
}
BAILOUT:

if s和for由编译器在内部转换为goto ,则它们的速度不会比goto

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM