重新初始化向量的最快方法是什么?

新手上路,请多包涵

将大向量的所有值重置为其默认值的最快方法是什么?

 struct foo
{
  int id;
  float score;
};

std::vector<foo> large_vector(10000000);

最简单的方法是创建一个新向量,但我想重新分配内存比重新初始化现有向量需要更多时间?

在重置它之前,我必须遍历向量以收集非零分数(可能是数千或数百万)。我应该在这个循环中一一重置结构吗?

编辑:

向量大小是固定的,“默认值”意味着每个结构成员(所有浮点数和整数)都为 0。

原文由 Ben 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 762
2 个回答

为了确定最快的方式,您需要运行一些基准测试。

有许多不同的方法可以“重新初始化”一个向量:

  1. 调用 clear() ,对于普通类型,这应该大致相当于只做 vector.size = 0 。向量的容量不会改变,也不会释放任何元素。如果元素存在,将对元素调用析构函数。当您 push_backemplace_backresize 向量旧值将被覆盖。
  2. 调用 assign() ,例如 large_vector.assign( large_vector.size(), Foo() ); 。这将遍历整个向量,将每个元素重置为其默认值。希望编译器能够将其优化为 memset 或类似的。
  3. 由于您的类型很简单,如果您只想将每个元素重置为 0 您应该能够执行 memset ,例如: memset( large_vector.data(), 0, sizeof(Foo)*large_vector.size() );
  4. 调用 std::fill 例如 std::fill( large_vector.begin(), large_vector.end(), Foo() ); ,这应该类似于 assignmemset

原文由 Alan Birtles 发布,翻译遵循 CC BY-SA 4.0 许可协议

重新初始化向量的最快方法是什么?

不。

只需通过调用 clear() 来记录向量没有有效条目的事实。这具有(可能)最优、保证正确以及完美表达的优点。除非分析显示实际需要,否则 IMO 不应考虑任何建议的替代方案。

您的元素类型是微不足道的,因此复杂性的线性上限实际上应该是恒定的,以实现良好的质量实现 - 无需依次销毁每个元素。

没有内存被释放,或者以后需要重新分配。

You’ll just need to push_back or emplace_back when you’re writing into the vector after clear() ing, instead of using operator[] .

为了使这与第一次使用保持一致,不要使用 10000000 个值构造元素初始化向量,而是使用 reserve(10000000) 进行预分配而不进行初始化。

例如。

 int main() {
  vector<foo> v;
  v.reserve(10000000);

  while(keep_running) {
    use(v);
    v.clear();
  }
}

// precondition: v is empty, so
// don't access v[i] until you've done
//   v.push_back({id,score})
// at least i+1 times
void use(vector<foo> &v) {
}


由于您需要将元素就地归零,因此第二快的通用解决方案可能是将上面的循环更改为

  while(keep_running) {
    v.resize(10000000);
    use(v);
    v.clear();
  }

或者删除 clear() 并使用 fill() 覆盖所有元素。

如果非零元素是稀疏的,如果您根据一些有意义的索引更新它们可能是这种情况,当您的主循环遍历向量时,动态地将它们归零可能会更快。

同样,您确实需要进行 分析 以找出哪个更适合您的用例。

原文由 Useless 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题