首先创建字符串然后通过移动语义将其添加到向量或在向量中创建元素是不是具有内存效率?

Posted

技术标签:

【中文标题】首先创建字符串然后通过移动语义将其添加到向量或在向量中创建元素是不是具有内存效率?【英文标题】:Is it memory efficient to first create string and then add it to vector through move semantics or to create element in vector?首先创建字符串然后通过移动语义将其添加到向量或在向量中创建元素是否具有内存效率? 【发布时间】:2016-02-03 10:32:52 【问题描述】:
std::vector<std::string> v;
v.push_back("");
v[0] += 's';
v[0] += 't';
v[0] += 'r';
v.push_back("");
v[1] += 's';
v[1] += 't';
v[1] += 'r';

std::vector<std::string> v;
std::string s = "";
s += 's';
s += 't';
s += 'r';
std::string s1 = s;
v.push_back(std::move(s));
v.push_back(std::move(s1));

在第一种情况下,我们首先在向量中创建元素,然后对其进行修改。我想在如此小的情况下,首先会保留足够的内存,但如果不是 - 将是向量v 在内存中连续,还是只是指向字符串对象的指针?将元素添加到向量中的字符串元素是否会使最后一个执行内存重新分配?

在第二种情况下,是否会为用作右值的字符串分配内存并直接添加到分配的某处向量中,而无需为字符串重新分配内存?

【问题讨论】:

您可以使用自定义分配器编写代码,该分配器记录其操作并亲自查看! 重新标题:一句话,“是”。 即使使用移动语义,目标字符串仍然需要初始化。所以你正在初始化两个字符串而不是初始化一个字符串。你怎么看? 请注意,由于小字符串优化,std::string 的移动可能不一定便宜。这是否对您的程序有任何实际的性能影响是另一回事。 【参考方案1】:

std::vector 始终将数据存储在连续的内存块中。 在这两种情况下,如果strings 你想推回不能放入 已经分配的内存,会有重新分配。

通过v.push_back(std::move(s)),数据将被移动到vector中的std::string 来自s,因此s 数据的未使用副本不会保留在内存中。 这对于大量数据可能更有效,但在您的情况下,这 不会有太大区别。

在第二种情况下,您还必须再初始化两个strings...

【讨论】:

非常需要注意的是,只有字符串对象连续存储在向量中,而不是用于实际字符串数据的堆内存。 (当然有短字符串优化可以在内部存储短字符串以避免短字符串堆)

以上是关于首先创建字符串然后通过移动语义将其添加到向量或在向量中创建元素是不是具有内存效率?的主要内容,如果未能解决你的问题,请参考以下文章

新书自然语言处理嵌入:语义向量表示理论与进展,从Word2Vec到BERT,163页pdf

在向外部依赖项添加扩展时中止陷阱6

如何把纯化标签加上去

创建动画和移动相机

将图像添加到响应式网站,然后将其发送到 SQL 数据库

将结构添加到字节向量,然后添加另一个[关闭]