两种数字比较方式中的哪一种更有效

时间:2015-04-01 01:09:52

标签: c++ c

在一个数字比较函数中,我们可以使用if子句,一个是if else使用,另一个是直接使用return。因为如果它没有返回大的那个,那么另一个肯定是更大的那个。

现在问题是:哪个更有效率?我测试时机功能无法区分。

方法A:

int getmax(int a,int b){
  if (a>b)return a;
  else return b;
}

方法B:

int getmax(int a,int b){
  if (a>b)return a;
  return b;
}

很抱歉让你们中的一些人不高兴。我有这个问题是因为我想知道else子句对时间的贡献。 else条款会花费更多时间吗?虽然我在for循环中运行了1亿次,但似乎是随机效率。

4 个答案:

答案 0 :(得分:2)

如果进行这样的比较,我认为没有意义,但如果你真的好奇,让我们比较VC11生成的汇编:

int getmax_1(int a,int b)
{
    if (a>b)
        return a;
    else
        return b;
}

int getmax_2(int a,int b)
{
    if (a>b)
        return a;

    return b;
}

<强> getmax_1

    if (a>b)
002017BE  mov         eax,dword ptr [a]  
002017C1  cmp         eax,dword ptr [b]  
002017C4  jle         getmax_1+2Dh (02017CDh)  
    return a;
002017C6  mov         eax,dword ptr [a]  
002017C9  jmp         getmax_1+30h (02017D0h)  
    else
002017CB  jmp         getmax_1+30h (02017D0h)  
    return b;
002017CD  mov         eax,dword ptr [b]

<强> getmax_2

    if (a>b)
002017FE  mov         eax,dword ptr [a]  
00201801  cmp         eax,dword ptr [b]  
00201804  jle         getmax_2+2Bh (020180Bh)  
    return a;
00201806  mov         eax,dword ptr [a]  
00201809  jmp         getmax_2+2Eh (020180Eh)  
    return b;
0020180B  mov         eax,dword ptr [b]  

然而,这是一个Debug构建。在发布版本中,这两个调用肯定会内联,第二个函数中的附加调用可能会被删除。

所以...没有区别,真的。

答案 1 :(得分:0)

我强烈建议使用第二个选项,因为它基本上做同样的事情,但没有任何额外的代码。你可以这样看待它:

函数在return语句处转义,并且可能返回指定的值。话虽如此,在if语句之后逃避函数已经是一个好主意,并且没有任何问题。 return之后的if语句将退出该函数,之后不考虑任何代码。这意味着else是不必要的,并且只是编译器的额外工作,而且没有必要。

答案 2 :(得分:0)

绝对没有区别。 else子句不生成任何可执行代码。在机器指令级别,给定地址只有条件和无条件分支。在C中排序goto

所以你的两个函数都会这样执行:

    if (a > b) goto label_1;
    return_register = b;
    goto label_2;
label_1:
    return_register = a;
label_2:
    return return_register;

答案 3 :(得分:0)

我看到它的方式,你已经问过一个或另一个在C或C ++领域是否有效 The C standard说:

  

在抽象机器中,所有表达式都按语义指定的方式进行计算。一个   实际实现不需要评估表达式的一部分,如果它可以推导出它   不使用值,不产生任何副作用(包括由...引起的任何副作用)   调用函数或访问volatile对象。)

C ++标准有类似之处。

由于我们缺少关于实际实施的关键细节(例如,一段代码是非最优的而另一条是否是最优的),并且标准没有指定效率

em>,你的问题没有明确的答案......至少,在C或C ++领域 。您必须标记编译器的任何内容,而不是[c]和[c ++]。

可能影响该计划效率的其他因素是......嗯......程序!众所周知,随着代码和数据的增长,缓存未命中的风险也随之增加。由于这个原因,你可能不应该自己测试这段代码:没有任何有意义的东西,因为这些数字会在你改变某些东西时改变。

出于这个原因,我们经常通过解决现实问题易于阅读且易于编写代码来避免过早优化 。一旦您获得了解决实际问题的解决方案(以及您的老板对其进行优化的权限或请求),请使用 profiler 确定最重要的瓶颈,并尝试优化这些瓶颈。

如果您尝试在其他任何地方进行优化,特别是通过引入额外的代码或数据来减少其他地方的代码或数据,那么您可能会进一步推动更加重要的优化。

一旦您优化了最重要的瓶颈,再次使用您的探查器确保优化成功,并确定可以优化的其他区域。

有一天,这可能很好地挽救了你的工作......