C++编译器能优化掉一个类吗

Can C++ compilers optimize away a class?

本文关键字:一个 编译器 优化 C++      更新时间:2023-10-16

假设我有一个类似这样的类:

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是一个很好的工具。

  • 想要速度?测量(霍华德·欣南特)

通常,编译器不会优化类。通常,它们会优化功能。

编译器可能会决定采用简单内联函数的内容,并将内容粘贴到调用函数的位置,而不是将内联函数设置为硬编码函数(即它将具有地址)。此优化取决于编译器的优化级别。

编译器和链接器可能会决定删除未使用的函数,无论它们是类方法还是独立函数。

将类视为描述对象的模具。如果没有实例,模具就不好。一个例外是类中的公共静态函数(静态方法不需要对象实例)。类通常保存在编译器的字典中。

相关文章: