【问题标题】:Is the goto statement slow in c#?c# 中的 goto 语句慢吗?
【发布时间】:2012-04-19 17:31:13
【问题描述】:

我正在开发一个 C# .NET 应用程序,该应用程序在大量数据(平均 1000 万个数据点)上使用了一些相当复杂的科学公式。我正在做的部分工作需要尽可能优化公式实现。

我注意到一个公式实现使用了 goto,这让我想知道:goto 是否比其他流控制结构慢?

【问题讨论】:

  • 请帮自己一个忙,不要在C#中使用goto!!!
  • @MUG4N goto 没有错,只是你使用它们的方式让它们变得邪恶
  • 我投票决定重新开放。这不是关于goto 有用性的问题。这个问题的措辞是询问性能。这是一个合理的问题,无论个人是否厌恶它的使用。
  • @Servy:说实话,我从未真正看到过不负责任地使用goto。我怀疑这是因为 1) 大多数初级开发人员不知道它的存在,以及 2) 使用它的禁忌让其他所有人都回避(理所当然)。我见过它的唯一一次使用(当然除了代码生成器)是出于合理(尽管有争议)的理由这样做的。
  • 我已经存在足够长的时间了,以至于我看到 goto 被不负责任地使用,但那是 20 多年前在古代 FORTRAN 中的事了。从那以后,我再也没有看到它被不负责任地使用过。有时,它是最干净、最清晰、最可维护的解决方案。它绝对没有错,这种歇斯底里是愚蠢的。

标签: c# goto


【解决方案1】:

goto 是否比其他流控制结构慢?

没有。无论如何,所有其他流控制结构基本上都是goto

【讨论】:

  • 这是一个完全合理的问题。当人们看到与goto 有任何关系时,他们只会发自内心地做出反应。
【解决方案2】:

C# 中的goto 指令并不比任何其他控制流构造慢。事实上,绝大多数控制流构造(if、while、for 等)都是根据goto 实现的。

例如:

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

基本上是编译成下面的

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

【讨论】:

    【解决方案3】:

    我注意到一个公式实现使用 goto,这让我 想知道:goto 是否比其他流控制结构慢?

    goto 不会比任何其他流量控制机制慢。它像大多数流控制机制一样被编译成br.s(或类似的)MSIL 指令。但是,在某些情况下,goto 可能会稍微快一些。它们主要限于涉及在嵌套循环中使用breakcontinue 的情况。考虑以下代码。

    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
                }
            }
        }
    }
    

    您可以通过多种不同的方式打破整件事。这是一种方法。

    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;
    }
    

    问题是每个循环都必须检查condition 标志。我们可以用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:
    

    【讨论】:

    • +1 是 goto 何时是最干净、最可维护的解决方案的绝佳示例。另一个示例是具有许多潜在错误条件的代码,它们都使用 goto 来解决常见的错误退出。
    【解决方案4】:

    ifs 和 for 在内部由编译器转换为 gotos,因此它们的速度不会比 gotos 快

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 2012-08-08
      相关资源
      最近更新 更多