传递大数据向量的更好方法

时间:2013-12-02 19:36:41

标签: c++ boost stl

需要设计一个返回BigClass数组的函数。为了防止不必要的复制,我有两种选择。

struct BigClass
{
    int manyfields;    
};

boost::shared_ptr<vector<BigClass> > Fun1()
{
    throw;
}

vector<boost::shared_ptr<BigClass> > Fun2()
{
    throw;
}

问题&GT;哪种方法更好?如果以上都不好,请提供更好的。

谢谢

5 个答案:

答案 0 :(得分:3)

VS2010允许您使用移动语义。

这意味着:
std::vector<BigClass> retBigVector() { return std::vector<BigClass>(); }可以正常使用。
retBigVector将构建一个大向量并将其移动到您希望的任何位置。

这是移动语义出现的主要原因之一 - 再次,VS2010支持这一点。

答案 1 :(得分:1)

如果没有返回值优化,boost::shared_ptr<vector<BigClass> >的开销低于vector<boost::shared_ptr<BigClass> >。第一个复制一个指针,第二个复制N向量内部的指针。

此外,第二种形式具有较少的缓存/内存一致性。每个BigClass都在堆上单独分配,而在第一种形式中,所有BigClass都在一个连续的块中。

答案 2 :(得分:0)

shared_ptr&gt;需要更少的内存,特别是对于大型向量;矢量&gt;更灵活,因为它允许记忆意识的矢量操作,如添加/删除元素或排序。

如果你的矢量具有可管理的大小,我会选择Fun2。如果您的向量很大并且您确信返回的向量将用于只读,请使用Fun1。

答案 3 :(得分:0)

尝试boost :: vector_ptr: http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/ptr_vector.html

然后您可以通过常用的[]运算符获取指针。许多其他ptr_containers都可用。

答案 4 :(得分:-1)

通常,您不应该创建POD数据类型的vector / array / other容器,因为这会为切片问题创建机会(http://en.wikipedia.org/wiki/Object_slicing)。 它还会在复制值类型时产生问题。

那就是说,你提出的解决方案都不是“理想的” - 其中一个会产生切片问题,另一个通常会复制整个阵列。

完美的解决方案实际上取决于您创建BigClass向量的位置 1.如果你在Fun2 / Fun2中创建它 - 最简单的方法是在创建它之后返回一个指向它的共享指针。如果编译器支持NRVO(命名返回值优化),您也可以按值返回,并避免复制 2.如果大数据的Vector存储在其他地方(例如,类的成员),则可以返回对它的引用,假设您不想复制整个向量(即调用者)该函数将能够更改原始矢量)