Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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++ 添加到C+中的集合之前或之后+;_C++_Performance_Stdvector - Fatal编程技术网

C++ 添加到C+中的集合之前或之后+;

C++ 添加到C+中的集合之前或之后+;,c++,performance,stdvector,C++,Performance,Stdvector,给定 或 如果向量包含指向my_类型的指针,那么这两个类型看起来几乎相同 然而,当复制整个my_类型对象(如本例中所示)时,我认为第二个会更快,因为要复制的数据更少,因为额外的数据只有在“m”位于“v”内之后才存在 编辑: 在我的程序示例中,我的_类型看起来有点像这样 v.push_back(m); v[0].generate_data_inside_self(); myu类型 { 私人: std::vector data;//构造后为空 公众: //无析构函数、赋值运算符 //复制构造函数等

给定

如果向量包含指向my_类型的指针,那么这两个类型看起来几乎相同

然而,当复制整个my_类型对象(如本例中所示)时,我认为第二个会更快,因为要复制的数据更少,因为额外的数据只有在“m”位于“v”内之后才存在

编辑:

在我的程序示例中,我的_类型看起来有点像这样

v.push_back(m);
v[0].generate_data_inside_self();
myu类型
{
私人:
std::vector data;//构造后为空
公众:
//无析构函数、赋值运算符
//复制构造函数等。显式(被)定义
在\u self()中生成\u data\u//填充数据
{
//例如,包含填充的循环
//“数据”包含一些(比如说50个)值
}
}

对不起,这太取决于你的类型了。如果它持有指向某个大型外部数据块的指针,那么复制它可能根本不需要时间,但您会发现在生成数据后复制它的速度非常慢。只有你知道,如果你关心性能,唯一的办法就是在
循环中对它进行重击并计时。

除非你给我们更多的数据,我认为这取决于你的类包含什么以及它必须生成什么数据。很难判断哪个更快,因为可能有一些事情我们无法从您的问题中判断。

在两个示例中,
m
的大小都是固定的。在
generate\u data\u inside\u self()
中生成的任何数据要么只是填补漏洞,要么是分配
vector
不关心的空间(即堆上)


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

如果您担心这里的性能,请不要使用
std::vector
。Vector将在每次内存重新分配时复制所有元素,并可以在元素擦除时从Vector复制元素。使用
boost::ptr_vector
std::vector
,这可以提高两种情况下的性能:向vector添加元素和重新分配/擦除

编辑:

我修改了我的回答:


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

这取决于类型的定义方式以及调用的函数的功能

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

因此,答案取决于
在self中生成数据是否会使副本更昂贵。这取决于赋值运算符的定义。(以及在C++11中是否存在移动赋值运算符,以及是否允许调用该运算符。)


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

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


如果您有许多向量副本,并且担心性能,我的建议是使用指针的
向量和
新的
(当然有一天
删除
)对象并将它们放入
向量中。这样,插入向量的成本并不取决于对象的复杂性。

我想我理解你的意思,这意味着“我的类型”中的内部“数据”(参见我在问题中添加的额外信息)是一种指针,而复制我的类型实际上并不复制它的“数据”这只是一个禁忌。你能看看我提供的例子并澄清我对这一点的理解是正确的吗。
sizeof(m)
可能不会改变,但
m
的复制构造函数/赋值操作符的复杂性肯定会改变
vector
不仅仅是盲目复制内存块。谢谢。我刚刚为这个问题添加了更多的信息,以便得到更精确的答案。
std::vector
的性能按O(1)摊销。事实上,每次添加的成本不是
1
,而是
2
。这是一个很好的信息。我对你的答案投了赞成票。给出我的示例代码,在我的问题的底部显示我的_类型是如何定义的,答案是什么-P您还没有显示类型的完整定义。它的赋值(和移动赋值)操作符是什么样子的?它是否有其他数据成员?(为什么不简单地对其进行基准测试呢?)它的赋值和移动赋值运算符没有定义(它们是默认值),它的其他属性与问题无关,我最终不得不描述它所属的程序的更多部分,如果答案太具体,也不会对其他人有多大帮助。这将是有益的,不仅仅是知道它将在我的系统上运行得多快,我还没有意识到这是一个如此复杂的问题回答,或者C++的预言会起到显著的作用。我进一步澄清了问题。为什么构造函数不生成数据?需要用户调用某些成员函数才能使用的对象。在构建之后总是可用的。你的疯狂概括有时几乎肯定是错误的。除此之外,我的_类型会像e一样糟糕
m.generate_data_inside_self();
v.push_back(m);
v.push_back(m);
v[0].generate_data_inside_self();
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
        }
}