Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Can C++;编译器优化了一个类?_C++_C++11_Compiler Optimization - Fatal编程技术网

C++ Can C++;编译器优化了一个类?

C++ Can C++;编译器优化了一个类?,c++,c++11,compiler-optimization,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:

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

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::\u c恰好是std::shared\u ptr,是否仍然如此

绝对,是的,是的;只要它不违反(正如已经指出的)。这种优化是否真的发生是一个更有趣的问题;这是标准允许的。对于此代码:

#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);
}
#包括
#包括
模板
类视图{
公众:
视图(DataContainer&c):c(c){}
int getElemForCoords(双x,双y){
int idx=x*y;//一些愚蠢的计算
返回c->at(idx);
}
私人:
数据容器&c;
};
模板
视图生成视图(数据容器和c){
返回视图(c);
}
int main(int argc,char*argv[]){
自动ptr2vec=std::使_共享(2);
自动查看=生成视图(ptr2vec);
返回视图.getElemForCoords(1,argc);
}
我已经通过检查汇编代码(
g++-std=c++11-O3-S-fwhole program optaway.cpp
)验证了视图类好像不存在,它增加了零开销。


一些不请自来的建议

  • 检查程序的汇编代码;你会学到很多,并开始担心正确的事情
    shared_ptr
    是一个很重的物体(例如,与
    unique_ptr
    相比),部分原因是发动机罩下的多线程机器。如果查看汇编代码,您将更加担心共享指针的开销,而更少担心元素访问。;)

  • 代码中的
    inline
    只是噪声,该函数无论如何都是隐式内联的。请不要用内联关键字破坏你的代码;无论如何,优化器都可以将其视为空白。改用链接时间优化(
    -flto
    与gcc)。GCC和Clang是出人意料的智能编译器,能够生成良好的代码

  • 分析代码,而不是猜测和过早优化。这是一个很好的工具

  • 想要速度吗?量。(霍华德·希南)


如果编译器同时内联构造函数和函数,那么类就不会剩下太多了。@Mystical:是的,我想这是有道理的。我想确定的是,标准中没有奇怪的角落案例或保证限制编译器在这里可以做什么。是的。事实上,编译器可以应用任何不会改变程序可观察行为的转换,它们可以——而且确实可以——更改函数签名、拆分函数、合并函数、删除函数、用结果替换函数等等。这里有更多的细节:“可观察的行为”只是在程序之外可以观察到的:而不是通过使用调试器。优化器可以更改任何只能通过特殊工具观察到的内容。我之所以提到这一点,是因为有人在问C#问题时认为C#优化器违反了规则,因为某些代码没有按他认为的方式分配内存。澄清:类本身不会生成任何机器代码,所以编译器没有什么可优化的。@Oktalist:请澄清编译器如何处理带有公共静态成员函数的类,以及只包含函数的类。我想你的答案已经充分解释了这一点。可以优化成员函数中的代码,但不能优化类本身。我试图澄清这背后的原因。谢谢你的回答,阿里。是的,我没有把它添加到问题中,但我也在想,如果调用方已经有了共享的ptr,那么共享的ptr是否可以被优化掉。我想这对编译器要求太高了:P。至于内联关键字,我过去在头文件中包含代码时(带有保护)会出现“重复定义”错误,如果我没有明确声明它们为内联的话。@Siegfriedgevater我很高兴这个答案对我有帮助。如果实现普通函数而不是类成员函数,则会得到重复的定义;这些都是隐式内联的。模板也是隐式内联的。我明白了,我必须再试一次。