繁体   English   中英

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,那么同样如此吗?

绝对的,是的,是的 ; 只要它不违反as-if规则 (正如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 with gcc)。 GCC和Clang是令人惊讶的智能编译器并生成良好的代码。

  • 描述您的代码,而不是猜测和过早优化。 Perf是一个很棒的工具。

  • 想要速度? 测量。 (作者Howard Hinnant)

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM