在C ++中添加集合之前或之后

时间:2011-09-17 21:00:07

标签: c++ performance stdvector

鉴于

my_type m;
std::vector<my_type> v;

哪个运行得更快?

m.generate_data_inside_self();
v.push_back(m);

或者

v.push_back(m);
v[0].generate_data_inside_self();

如果向量保持指向my_types的指针,则两者看起来大致相同。

然而,当在整个my_type对象中进行复制时,如本例所示,我认为第二个会更快,因为额外的数据只有在“m”在“v”内部之后才会存在。

编辑:

在我的程序示例中,my_type看起来有点像这样。

my_type
{
    private:
        std::vector<unsigned short> data; //empty after construction

    public:
        //no destructors, assignment operators
        //copy constructors etc... explicitly (are) defined
        generate_data_inside_self() //populates data
        {
            //contains for example a loop that populates
            //"data" with some (lets say 50) values
        }
}

6 个答案:

答案 0 :(得分:1)

抱歉,但这在很大程度上取决于你的类型。如果它保存了指向某个大的外部数据块的指针,那么复制它可能基本上没有时间,但你会发现在生成数据后复制它的速度非常慢。只有你知道,如果你关心性能,唯一的方法就是在for循环中敲击它并计时。

答案 1 :(得分:1)

如果您担心此处的表现,请不要使用std::vector<my_type>。 Vector将复制每个内存重新分配的所有元素,并可以复制元素擦除上的元素。使用boost::ptr_vectorstd::vector<boost::shared_ptr>,可以在以下两种情况下提高性能:向向量添加元素并重新分配/删除。

修改

我修改了我的回答:

第二种方法具有更好的性能,因为在添加到向量时避免复制已填充的 my_type实例(与使用空std::vector成员的默认构造相反)。但它的可读性较差,而且规范较少。我建议使用第一种方法作为默认方法,并且只有在分析后才能有选择地使用第二种方法或者 - 我之前建议 - 使用boost::ptr_vectorstd::vector<boost::shared_ptr>

答案 2 :(得分:1)

当复制构造函数/运算符==的复杂度较小时添加它。如果要生成数据,最有可能增加复杂性,请在生成之前插入。

如果你有很多矢量副本并且你关心性能,我的建议是有一个vector指针和new(当然还有一天delete)对象和把它们放在vector中。这样,插入vector的成本不依赖于对象的复杂性。

答案 3 :(得分:0)

除非您提供更多数据,否则我认为取决于您的类包含的内容以及生成的数据。很难说哪个会更快,因为可能涉及的事情我们无法从你的问题中说出来。

答案 4 :(得分:0)

具体取决于类型的定义方式,以及您调用的函数的作用。

在这两种情况下,对象m在构造后都会被复制到向量中。

所以答案取决于generate_data_inside_self是否使副本更昂贵。这取决于如何定义赋值运算符。 (在C ++ 11中,是否存在移动赋值运算符,以及是否允许它被调用。)

但与性能问题一样,唯一重要的答案是运行代码时得到的答案。如果您想知道哪个更快,请为代码计时并亲自查看。

答案 5 :(得分:-1)

两个示例中都固定了m的大小。您在generate_data_inside_self()中生成的任何数据要么只是填充空洞,要么分配vector不关心的空间(即在堆上)。

更重要的是,从vector的角度来看,该数据的内容是不透明的,因此如果碰巧是全零或随机分类的值,它就不会影响性能;大小sizeof(m)的整个块都以任意方式复制。