我们说我的班级是这样的:
class View
{
public:
View(DataContainer &c)
: _c(c)
{
}
inline Elem getElemForCoords(double x, double y)
{
int idx = /* some computation here... */;
return _c.data[idx];
}
private:
DataContainer& _c;
};
如果我有一个使用这个类的函数,是否允许编译器完全优化它并只是内联数据访问?
如果View :: _ c恰好是std :: shared_ptr?
,是否仍然如此答案 0 :(得分:6)
如果我有一个使用这个类的函数,是否允许编译器 完全优化它,只是内联数据访问?
如果View :: _ c恰好是std :: shared_ptr?
,是否仍然如此
绝对,是的,是的;只要它不违反as-if rule(正如Pentadecagon已经指出的那样)。这种优化是否真的发生是一个更有趣的问题;它是允许的标准。对于此代码:
#include <memory>
#include <vector>
template <class DataContainer>
class View {
public:
View(DataContainer& c) : c(c) { }
int getElemForCoords(double x, double y) {
int idx = x*y; // some dumb computation
return c->at(idx);
}
private:
DataContainer& c;
};
template <class DataContainer>
View<DataContainer> make_view(DataContainer& c) {
return View<DataContainer>(c);
}
int main(int argc, char* argv[]) {
auto ptr2vec = std::make_shared<std::vector<int>>(2);
auto view = make_view(ptr2vec);
return view.getElemForCoords(1, argc);
}
我已经通过检查汇编代码(g++ -std=c++11 -O3 -S -fwhole-program optaway.cpp
)验证了 View
类就像它不存在一样,它增加了零开销。
一些未经请求的建议。
检查程序的汇编代码;你将学到很多,并开始担心正确的事情。 shared_ptr
是一个重量级的物体(例如,与unique_ptr
相比),部分原因在于引擎盖下的所有多线程机械。如果查看汇编代码,您将更加担心共享指针的开销,而不是元素访问。 ;)
代码中的inline
只是噪音,无论如何,该函数都是隐式内联的。请不要使用inline关键字删除代码;无论如何,优化器可以自由地将其视为空格。请改为使用链接时间优化(-flto
与gcc)。 GCC和Clang是令人惊讶的智能编译器并生成良好的代码。
对代码进行概要分析,而不是猜测并进行过早优化。 Perf是一个很棒的工具。
想要速度?测量。 (作者Howard Hinnant)
答案 1 :(得分:1)
通常,编译器不会优化远程类。通常,它们会优化功能。
编译器可以决定采用简单内联函数的内容并粘贴调用函数的内容,而不是使内联函数成为硬编码函数(即它将具有地址)。此优化取决于编译器的优化级别。
编译器和链接器可能决定删除未使用的函数,无论它们是类方法还是独立的函数。
将该类视为描述对象的模板。没有实例,模板就没有任何好处。一个例外是类中的公共静态函数(静态方法不需要对象实例)。该类通常保存在编译器的字典中。