当我想将数据从堆栈移动到向量时如何避免复制?

Posted

技术标签:

【中文标题】当我想将数据从堆栈移动到向量时如何避免复制?【英文标题】:How to avoid copy when i want to move data from stack to vector? 【发布时间】:2021-12-20 06:25:28 【问题描述】:

我有一个非常常用的操作,需要将数据从堆栈移动到向量中。

让我写一段演示代码:

void handle(const std::vector<std::vector<std::pair<size_t, double>>> & v)   // this is my handle data function



int main() 
  std::stack<std::vector<std::pair<size_t, double>>> data; // this is my data container, it's a stack
  int cnt = 0;
  std::vector<std::vector<std::pair<size_t, double>>> params(3);
  while (cnt++ < 3)    // assume this handle need 3 data
    const auto & v = data.top();
    params[cnt] = v;  // i think this will involve copy operation
    // and in real scene, i need to keep params in order,
    // so i cant use emplace back, only can use [i]
    data.pop();
  
  handle(params);

你能帮忙吗,我怎样才能避免复制和加快我的代码?

【问题讨论】:

您的代码从不修改源代码datadata 保持不变重要吗? (编辑 - 现在代码已更改) @klaus 你的意思是params[cnt] = v; 不会一个一个地复制矢量元素,只是移动参考并且非常快? params[cnt] = std::move(data.top()); 我不明白你为什么不能使用emplace_backpush_back 的解释。任何一个都应该在这里工作得很好。 @Klaus data.top() 返回的类型是 std::vector&lt;std::pair&lt;size_t, double&gt;&gt; (实际上是对它的左值引用) - 它 向量,而不是一对 size_tdouble。它非常可以移动。 @IgorTandetnik:你说得对……忘了吧,对不起! 【参考方案1】:

您的代码将创建向量的副本。

const auto & v = data.top();
params[cnt] = v;

这将通过向量移出data来避免复制。

auto & v = data.top();
params[cnt] = std::move(v);

这两种操作都被描述为形式 (1) 和 (2),in cpprefernce。

【讨论】:

我发现这两种方法具有相同的延迟。我使用 gcc -O3,编译器是否已经为我优化了这个,或者它们应该有不同的延迟(移动会快得多)? 我无法查看或评论您的延迟测试,但只要v 不是conststd::move 应该非常快 . @TedLyngmo 哈哈,复制自问题。

以上是关于当我想将数据从堆栈移动到向量时如何避免复制?的主要内容,如果未能解决你的问题,请参考以下文章

我可以使用 rebase 将提交从 dev 移动到 master 吗?

将数据移动到 Rc/Arc 是不是总是将其从堆栈复制到堆?

堆栈内存 /STACK

推力:基于另一个向量选择性地复制

如何将图像上传到 Cloudinary - MERN 堆栈

C++ 将元素从一个向量移动到另一个向量