我有一个简单的功能类似于:

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

最佳答案

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

您会发现这完全取决于Big_obj

例如。

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_obj(vect类型已从数组更改为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开关),但同样适用。

关于c++ - 使用只读变量的性能与直接存储在对象中的性能直接不同吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24095378/

10-11 07:34