C ++编译器可以优化一个类吗?

时间:2014-04-15 19:51:54

标签: c++ c++11 compiler-optimization

我们说我的班级是这样的:

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?

,是否仍然如此

2 个答案:

答案 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)

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

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

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

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