首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编译器可以内联在循环中生成对象的方法吗?

编译器可以内联在循环中生成对象的方法吗?
EN

Stack Overflow用户
提问于 2012-06-22 22:33:59
回答 4查看 114关注 0票数 2

出于我的好奇心,我想提个问题。我听说过很多次,在编写方法时最好使用复制/销毁范例。所以如果你有一个这样的方法:

代码语言:javascript
运行
复制
OtherClass MyClass::getObject(){
    OtherClass returnedObject;
    return returnedObject;
}

据推测,编译器将通过内联方法并在调用getObject的方法堆栈上生成类来优化这一点。我想知道在这样的循环中它是如何工作的

代码语言:javascript
运行
复制
for(int i=0; i<10; i++){
    list.push_back(myClass.getObject());
}

编译器是否会将10个OtherClass实例放在堆栈上,以便可以内联此方法,并避免在未优化的代码中发生的复制和销毁?下面这样的代码怎么样:

代码语言:javascript
运行
复制
while(!isDone){
     list.push_back(myClass.getObject());
    //other logic which decides rather or not to set isDone
}

在这种情况下,编译器不可能知道getObject将被调用多少次,因此可以假定它可以将任何内容预先分配给堆栈,所以我的假设是没有完成内联,每次调用该方法时,我将支付复制OtherObject的全部成本

我意识到所有的编译器都是不同的,这取决于编译器认为这段代码是最优的。我只是泛泛地说,大多数编译器最有可能的反应是什么?我很好奇这种优化是如何完成的。

EN

Stack Overflow用户

回答已采纳

发布于 2012-06-22 23:18:21

代码语言:javascript
运行
复制
for(int i=0; i<10; i++){
    list.push_back(myClass.getObject());
}

编译器是否会将10个OtherClass实例放在堆栈上,这样它就可以内联此方法,并避免在未优化的代码中发生复制和销毁?

它不需要在堆栈上放置10个实例来避免复制和销毁……如果有足够的空间返回一个对象,无论是否有返回值优化,它都可以重用该空间10次-每次通过列表push_back从相同的堆栈空间复制到一些新的堆分配内存。

编译器甚至有权分配新的内存,并安排myClass.getObject()直接在该内存中构造对象。

此外,如果优化器选择展开循环,它可能会调用myClass.getObject() 10次-即使有一些重叠或并行-如果它能以某种方式说服自己这会产生相同的总体结果。在这种情况下,它确实需要10个返回对象的空间,而且这取决于编译器是在堆栈上还是通过某种神奇的巧妙优化,直接在堆内存中。

在实践中,我希望编译器需要从一个堆栈复制到另一个堆--我非常怀疑任何主流编译器是否足够聪明,能够在堆内存中安排直接构造。循环展开和RVO是常见的优化方法。但是,即使两者都起作用,我希望每次对getObject的调用都会在堆栈上串行构造一个结果,然后将其复制到堆中。

如果你想“知道”,可以写一些代码来测试你自己的编译器。你可以让构造函数写出"this“指针值。

这样的代码怎么样:

代码语言:javascript
运行
复制
while(!isDone){
     list.push_back(myClass.getObject());
    //other logic which decides rather or not to set isDone
}

代码越复杂,越不地道,编译器作者就越不可能对其进行优化。在这里,您甚至没有向我们展示我们可以推测的复杂性级别。在您的编译器和优化设置中试用它,然后查看....

票数 2
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11158317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档