使用readonly变量的性能是否直接与存储在对象中然后使用它不同?

时间:2014-06-07 08:33:13

标签: c++ optimization reference const copy-constructor

我有一个类似的简单函数:

int foo(const Data& a, int pos)
{
    Big_obj x= (pos==1?a.x : a.y);//I just use x for reading
    return x.elem*x.elem;
}

(假设我忘记通过引用const Big_obj& x=...存储对象)

今天编译器可以将其优化为以下代码吗? :

int foo(const Data& a, int pos)
{
    if (pos == 1)
      return a.x.elem * a.x.elem;
    else 
      return a.y.elem * a.y.elem;
}

1 个答案:

答案 0 :(得分:3)

使用GCC有一个非常有用的编译器开关:-fdump-tree-optimized,它将在执行优化后显示代码。

您可以发现这一切都取决于Big_obj

E.g。

struct Big_obj
{
  int elem;
  int vect[1000];
};

struct Data { Big_obj x, y; };

g++ -Wall -O3 -fdump-tree-optimized将生成 .165t.optimized 文件,其中包含:

int foo(const Data&, int) (const struct Data & a, int pos)
{
  int x$elem;
  const struct Big_obj * iftmp.4;
  int _8;

  <bb 2>:
  if (pos_2(D) == 1)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  iftmp.4_4 = &a_3(D)->x;
  goto <bb 5>;

  <bb 4>:
  iftmp.4_5 = &a_3(D)->y;

  <bb 5>:
  # iftmp.4_1 = PHI <iftmp.4_4(3), iftmp.4_5(4)>
  x$elem_7 = MEM[(const struct Big_obj &)iftmp.4_1];
  _8 = x$elem_7 * x$elem_7;
  return _8;
}

这正是您发布的优化代码。但是,如果您更改Big_objvect类型已从数组更改为std::vector):

struct Big_obj
{
  int elem;
  std::vector<int> vect;
};

优化不再执行(即foo()也会为x.vect分配/取消分配内存。

在该示例中,原因是必须根据as-if rule实现优化:只允许不改变程序的可观察行为的代码转换。

operator new可以有一个自定义实现,计算它被调用的次数(这很难检测)。但即使没有自定义operator new,也存在其他问题(请参阅Does allocating memory and then releasing constitute a side effect in a C++ program?)。

使用其他编译器,您必须研究汇编代码(例如clang++ -S开关),但同样如此。