在C++中添加到集合之前或之后
Before or after when adding to sets in C++
给定
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
}
}
当复制构造函数/运算符==的复杂性较小时添加它。如果您正在生成数据,很可能会增加复杂性,请在生成之前插入。
如果您有许多向量副本,并且关心性能,我的建议是使用指针的vector
和对象的new
(当然还有一天delete
(,并将它们放在vector
中。这样,在vector
中插入的成本就不依赖于对象的复杂性。
对不起,这在很大程度上取决于您的类型。如果它包含指向某个大型外部数据块的指针,复制它可能根本不需要时间,但您可能会发现在生成数据后复制它非常慢。只有你知道,如果你关心性能,唯一的方法就是在for
循环中破解它并计时。
如果您担心这里的性能,请不要使用std::vector<my_type>
。Vector将在每次内存重新分配时复制所有元素,并且可以在元素擦除时从Vector复制元素。使用boost::ptr_vector
或std::vector<boost::shared_ptr>
,这在两种情况下都可以提高性能:向矢量添加元素和重新分配/擦除。
编辑:
我修改了我的答案:
第二种方法具有更好的性能,因为在添加到向量时避免了复制填充的my_type
实例(与使用空std::vector
成员构建的默认实例相反(。但它的可读性较差,也不太符合规范。我建议使用第一种方法作为默认方法,并且只有在分析之后才能选择性地使用第二种方法,或者正如我之前建议的那样,使用boost::ptr_vector
或std::vector<boost::shared_ptr>
除非你给我们更多的数据,否则我认为这取决于你的类包含什么以及它必须生成什么数据。很难说哪个会更快,因为可能涉及到一些我们无法从你的问题中判断出来的事情。
这取决于类型的定义方式以及您调用的函数的作用。
在这两种情况下,对象m
在被构造之后被复制到向量中。
因此,答案取决于generate_data_inside_self
是否会使拷贝成本更高。这取决于赋值运算符的定义方式。(在C++11中,是否存在移动分配运算符,以及是否允许调用它。(
但与性能问题一样,唯一重要的答案是运行代码时得到的答案。如果你想知道哪一个更快,给代码计时,自己看看。
m
的大小在两个示例中都是固定的。在generate_data_inside_self()
中生成的任何数据要么只是填充漏洞,要么是分配vector
不关心的空间(即堆上(。
更重要的是,从vector
的角度来看,该数据的内容是不透明的,因此,如果它恰好是全零或随机组合的值,则不会影响性能;大小为CCD_ 20的整个块以任何一种方式被复制。
- 在 OpenCV 的 namedWindow 之前或之后初始化 Tesseract
- 基于函数而不是集合的二分搜索或迭代器?
- 如何在集合中迭代替代元素(或进行特定大小的飞跃)?
- 在获取从文件到矢量的每一行之后,数字将被更改或销毁
- 如何获取二叉树(集合或映射)的根
- #pragma 一次位置:在 #include 之前或之后
- 如何更有效地从向量或集合中擦除元素?
- 快速报告 - 在显示准备报告之前或之后清除最后报告
- Winsockets - 身体之前和/或之后的奇怪字符
- 是在C 静态初始化之前或之后调用dllgetClassObject
- 是在默认构造函数之前或之后调用的初始化列表
- EOF 位:读取失败之前或之后
- 类型之前或之后的常量
- 变量名应该在名词之前或之后有形容词吗
- 在计算函数返回值之前或之后是否销毁了局部变量
- 在方法名称之前或之后放置常量、静态和虚拟
- 在C++中,构造函数是在对象创建之前或之后调用的
- 在自动销毁变量之前或之后创建的c++返回值
- 在C++中添加到集合之前或之后
- 第 n 个或大集合的任意组合