【问题标题】:Is it faster to return early or to let the code finish?提早返回还是让代码完成更快?
【发布时间】:2013-04-08 06:10:35
【问题描述】:

如果我有一个方法包含很多 if else 语句,例如:

public void myMethod()
{
    if(..)
    else if(..)
    else if(...)
    else if(...)
    else if(...)

    //and so on            
}

将 return 放在这些语句中会更快,以便在发现一个语句为 true 后不检查其余代码,还是让编译器命中结束括号会更快?

我想这归结为一个问题:return 语句是否有效?

编辑:问题的重点:假设您有一个不断运行的游戏循环,其中包含许多方法和“else ifs”的代码。如果我必须每秒更新 2000 个不同的对象 60 次,那就是每秒检查 120000 个“else ifs”(至少)。因此,随着时间的推移,问题的答案可能会产生影响。

【问题讨论】:

  • else 部分确保一旦找到匹配项“不检查其余代码”。如果你省略了else,那么你有一个真正的问题。
  • 正如我在下面所说的,我想知道跳过未检查的行所花费的时间,而返回可能能够避免找到行尾并继续前进和那里。

标签: c# performance if-statement return


【解决方案1】:

没关系。
任何理智或疯狂的编译器都会为任一选项生成相同的字节码。 (假设你写的代码其实是等价的)

您应该使用更具可读性的方法。

【讨论】:

  • 感谢您的快速回复!
【解决方案2】:

当用作条件的保护时它是有效的,但在你的情况下它并不重要,因为一旦执行了这些语句中的一个,其他语句就不会被验证,但是如果你正在做这样的事情:

if(...){return;}
if(...){return;}
if(...){return;}
if(...){return;}
if(...){return;}

那就有关系了。

【讨论】:

  • 是的!这就是我指定 if else 语句的原因。
  • 那么你很伟大,那里没有任何好处,但作为一般情况,带有返回语句的保护条件更好,更易读。
  • @svick,我更新了答案,所以它变得更像 c# 了。
【解决方案3】:

SLaks 的回答当然是正确的。但我认为你提出这个问题的事实表明你对 if-else 的含义有误解。当你说

if(x) X();
else if(y) Y();
else if(z) Z();
return;

意思和

完全一样
if(x)
{
  X();
}
else
{
  if (y)
  {
    Y();
  }
  else
  {
    if (z)
    {
      Z();
    }
  }
}
return;

例如,如果分支x 被采用,则永远不会检查y;控制在X() 之后直接跳转到return

事实上,C# 中没有“else if”之类的东西——或者 C、C++、Java 或 JavaScript。只有“其他”;如果你碰巧在else 后面加上if 声明,那是你的事。没有比这更多的“else if”了

if (x) X();
else while(y) Y();

是一个“else while”语句。您可以在else 之后添加任何您想要的语句;大多数人选择放置if 或块语句,但你可以在其中放置任何你喜欢的语句。(*)

更新:

我知道 else if 'skips',问题的重点是添加一个 return 让它直接跳出来,而不是花时间跳过它们。例如,在极端情况下,连续一百万个 if else 语句。它仍然需要找到行尾(这可能需要时间)。我对吗?

好的,我们需要进入一个更低的级别。 if-else 语句编译如下:

if (condition) 
    Consequence() 
else 
    Alternative();
Continuation();

实际上转化为一系列goto语句:

if (!condition) 
    goto ALTERNATIVE;
Consequence();
goto CONTINUATION;
ALTERNATIVE:  Alternative();
CONTINUATION: Continuation();

如果你有

if (x) X(); 
else if (y) Y();
else if (z) Z();
return;

首先变成

if (x)
    X(); 
else 
{
    if (y)
        Y();
    else
    {
        if (z)
            Z();
    }
}

然后变成

if (!x) goto XALTERNATIVE;
X(); 
goto CONTINUATION;
XALTERNATIVE: if (!y) goto YALTERNATIVE;
Y();
goto CONTINUATION;
YALTERNATIVE: if (!z) goto CONTINUATION;
Z();
CONTINUATION: return;

这能回答你的问题吗?


(*) 本地声明除外; C# 禁止这样做。

【讨论】:

  • 你是对的;我错过了关于未检查其余代码的部分。这是一个非常重要的澄清点。
  • 我知道 else if 'skips',问题的关键是添加一个 return 让它直接跳出来,而不是花时间跳过它们。例如,在极端情况下,连续一百万个 if else 语句。它仍然需要找到行尾(这可能需要时间)。我说的对吗?
  • @Colton:我已经更新了我的答案来解决你的新问题。简短的回答是否定的,连续有多少个“如果”并不重要;找到“return”仍然只是一个“goto”。
  • @Colton:另外,关于性能的两件事。首先,如果您想知道两件事中哪一个更快,双向编写,拿出一个秒表,双向运行,然后您就会知道哪个更快。不要在网上问陌生人哪个更快;你可以很容易地找到自己。其次,您要问的是什么是最多可以节省几纳秒的优化。我向你保证,你可能会担心更大的问题。使用分析器找到慢点并专注于它们。
猜你喜欢
  • 1970-01-01
  • 2015-06-29
  • 2019-11-30
  • 1970-01-01
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2018-11-16
相关资源
最近更新 更多