C++编译器能优化掉一个类吗
Can C++ compilers optimize away a class?
假设我有一个类似这样的类:
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,情况是否仍然如此?
如果我有一个函数使用这个类,编译器是否允许完全优化它,只内联数据访问?
如果View::_c恰好是std::shared_ptr,情况是否仍然如此?
当然,是的,是的;只要它不违反好像规则(正如Pentadegon已经指出的)。这种优化是否真的发生是一个更有趣的问题;这是标准允许的。对于此代码:
#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是一个很好的工具。
想要速度?测量(霍华德·欣南特)
通常,编译器不会优化类。通常,它们会优化功能。
编译器可能会决定采用简单内联函数的内容,并将内容粘贴到调用函数的位置,而不是将内联函数设置为硬编码函数(即它将具有地址)。此优化取决于编译器的优化级别。
编译器和链接器可能会决定删除未使用的函数,无论它们是类方法还是独立函数。
将类视为描述对象的模具。如果没有实例,模具就不好。一个例外是类中的公共静态函数(静态方法不需要对象实例)。类通常保存在编译器的字典中。
- C++,我收到一个无法理解的编译器错误
- 当类型适当的构造函数可用时,为什么一个编译器尝试使用已删除的副本构造函数
- 编译器在C++中调用另一个函数时,在参数中查找已删除的构造函数
- 为什么 MSVC C++编译器将一个简单的 Hello World 扩展为 4000 行汇编?
- 在另一个编译器中打印乱码的数组 |C++
- 一个C++编译器是为不同的平台(Linux,Windows等)多次编写的,这是真的吗?
- Qt 5测试版2,Qt Creator 2.6,MSVC错误:Qt Creaator需要一个编译器来构建.在工具包选项中
- 为什么当我通过引用传递数组时,我会收到一个编译器错误,指出我的变量未定义
- 我能否获得一个C++编译器在编译时实例化对象
- 我有编译器的情况。当我运行代码来去除一串特殊字符时,它在一个编译器中运行,但在另一个编译器中不运行?
- 我认为这是一个编译器错误,这不应该影响我的代码,但它是
- 一个编译器中的运算符优先级不同,为什么
- 有符号整数溢出为负数:这是一个编译器错误,还是我误解了优化
- Bjarne 对这个 ADL 示例的看法是错误的,还是我有一个编译器错误
- 为什么不可能构建一个编译器来确定C++函数是否会更改特定变量的值
- QT需要建立一个编译器
- 我需要破解一个c++编译器来发出和解释一个特定的类指针作为全局数组内的索引
- 为什么一个C程序编译并链接到一个C编译器,然后在运行时SIGILL
- sizeof可以应用于未捕获的变量的lambda内部吗?还是这是一个编译器错误?
- 为什么这是一个编译器错误?(g + +)