我有一个简单的功能类似于:
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/