假设我有一个产生大结构的函数(在本例中是一个巨大的std :: vector),以及一个重复调用它的循环:
std::vector<int> render(int w, int h, int time){
std::vector<int> result;
/* heavyweight drawing procedures */
return result;
};
while(loop){
std::vector<int> image = render(800,600,time);
/*send image to graphics card*/
/*...*/
};
我的问题是:在类似的情况下,GCC / Clang是否足够智能以避免在每次迭代时为该巨大的800x600x4阵列分配内存?换句话说,此代码的执行类似于:
void render(int w, int h, int time, std::vector<int>& image){ /*...*/ }
std::vector<int> image;
while(loop){
render(800,600,time,image);
/*...*/
}
为什么这样的问题:我正在从一种语言到C ++编写一个编译器,我必须决定我走哪条路;如果我像第一个例子那样编译它或像最后一个例子那样编译它。第一个是微不足道的;最后一个需要一些棘手的编码,但如果速度要快得多,那就值得。
答案 0 :(得分:1)
按值返回除了最简单的对象之外的所有对象将在99%的时间内更慢。如果向量的长度是无限的,构建整个std::vector<int>
的副本的工作量将是巨大的。此外,这是一个潜在的下溢你的堆栈的好方法,如果你的向量最终有1,000,000个元素。在您的第一个示例中,每次通过循环时,image
向量也将被复制构造和销毁。您始终可以使用-pg选项编译代码以打开gprof数据并检查结果。
答案 1 :(得分:1)
- &GT;去2。
答案 2 :(得分:1)
最大的问题不是内存分配,而是复制返回时发生的整个矢量。所以第二种选择要好得多。在你的第二个例子中,你也在重复使用相同的向量,它不会为每次迭代分配内存(除非你在某个时候做image.swap(smth))。