【问题标题】:Performance difference between else if( cond ) {} and else { if( cond ) {} }else if( cond ) {} 和 else { if( cond ) {} 之间的性能差异
【发布时间】:2013-05-01 12:50:50
【问题描述】:

我今天重写了一些旧代码以对其进行优化并使其更易读(因为其中一些注释非常粗劣),我想知道这些代码块之间是否存在任何技术性能差异:

if( cond1 )
{
     // Do something.
}
else if( cond2 )
{
     // Do something else.
}

还有:

if( cond1 )
{
     // Do something.
}
else 
{
     if( cond2 )
     {
          // Do something else.
     }
}

我对自己说不应该有性能成本,因为应该进行相同数量的比较,但我只是好奇是否有什么我忽略了。

【问题讨论】:

  • 完全没有区别。如果这种差异甚至通过语法分析,我会感到惊讶,更不用说它在代码生成期间造成差异了。
  • @john 关于解析的要点。为了促进代码生成,我可以想象一个编译器将单子复合语句替换为唯一的子语句。

标签: c++ performance conditional


【解决方案1】:

那么,让我们看看使用真正的编译器是否有任何不同。

以下代码:

int foo(int a, int b)
{
  if(a)
    return 5;
  else if(b)
    return 2;
  else
    return 56582201;
}

int bar(int a, int b)
{
  if(a)
    return 5;
  else
  {
    if(b)
      return 2;
    else
      return 56582201;
  }
}

当使用 GCC 4.8.0 编译时,调用为 g++ a.cpp -fdump-tree-gimple -c(没错,没有优化)给出以下 GIMPLE(GCC 的内部表示):

int foo(int, int) (int a, int b)
{
  int D.2205;

  if (a != 0) goto <D.2203>; else goto <D.2204>;
  <D.2203>:
  D.2205 = 5;
  return D.2205;
  <D.2204>:
  if (b != 0) goto <D.2206>; else goto <D.2207>;
  <D.2206>:
  D.2205 = 2;
  return D.2205;
  <D.2207>:
  D.2205 = 56582201;
  return D.2205;
}


int bar(int, int) (int a, int b)
{
  int D.2211;

  if (a != 0) goto <D.2209>; else goto <D.2210>;
  <D.2209>:
  D.2211 = 5;
  return D.2211;
  <D.2210>:
  if (b != 0) goto <D.2212>; else goto <D.2213>;
  <D.2212>:
  D.2211 = 2;
  return D.2211;
  <D.2213>:
  D.2211 = 56582201;
  return D.2211;
}

如您所见,区别在变量名和标签名上,无论如何这些都会在以后被丢弃。

使用 Clang 编译会得到类似的结果:LLVM IR 实际上是相同的。

所以不,没有区别,即使你在没有优化的情况下编译

【讨论】:

  • 我无法 +1 足以展示真实的“IRL”证明。
【解决方案2】:

它们完全一样。编译器不会完全按照您编写的代码编译代码。仅仅因为您编写内容的方式有所不同,并不意味着编译的可执行文件有所不同。只要结果程序的行为符合 C++ 标准的描述,就可以随意操作它。这被称为假设规则。由于根据标准,您提供的两个代码示例具有完全相同的行为,因此编译器可能会将它们编译为相同的可执行文件。

【讨论】:

    【解决方案3】:

    就语言而言,这两种结构是相同的。生成的代码也应该相同。

    【讨论】:

      【解决方案4】:

      不,不是碎片。值得怀疑的是,任何编译器都会为这些生成不同的代码。

      【讨论】:

      • FWIW,我在 gcc 中尝试过,它为两种情况生成完全相同的汇编代码。
      猜你喜欢
      • 2019-02-25
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 1970-01-01
      相关资源
      最近更新 更多