【问题标题】:Copying std::vector by element more optimized than moving the whole vector按元素复制 std::vector 比移动整个向量更优化
【发布时间】:2020-08-20 06:21:03
【问题描述】:

我试图通过引用一个构造函数来传递自定义对象的 std::vector,该构造函数将其复制/移动到另一个私有 std::vector 成员,但是以某种方式在 for 循环中逐个元素复制它会生成一个较小的程序比一次移动整个向量时的大小。

通常我的构造函数中有这段代码:

constructor(std::vector<object*>& newVec)
{
  for(int i=0; i<newVec.size(); ++i)
    this->vec.push_back(newVec[i]); 
}

这会生成一个比使用 std::move 更小的 Linux 可执行文件,如下所示:

constructor(std::vector<object*>& newVec)
{
   this->vec=std::move(newVec);
}

只有通过切换这两个 sn-ps,我才能从 30kB 大小传递到 35kB。

PS:向量中包含的对象与构造函数对象不同。

谁能解释一下为什么前一个版本比后一个版本更优化?

【问题讨论】:

  • 二进制大小 =/= 优化级别 =/= 速度。
  • 您是专门询问优化输出二进制大小,还是将大小优化与其他类型的优化混为一谈?
  • 未使用的模板函数不会生成,因此,如果它是您移动矢量的唯一位置...
  • 尝试godbolt.org比较生成的程序集。
  • 也许值得注意的是,这两个 sn-ps 并不等价。第二个将使参数为空,这可能不是您想要的。

标签: c++ c++11 vector stl


【解决方案1】:

我正在尝试通过引用将其复制/移动到另一个私有 std::vector 成员的构造函数来传递自定义对象的 std::vector

在这种情况下,您不应该使用左值引用参数。

按值传递,或 r 值引用。

此外,最好直接初始化成员,而不是默认初始化然后移动分配。

谁能解释一下为什么前一个版本比后一个版本更优化?

可能有很多潜在的原因:

  • 您可能尚未启用编译器优化。
  • “更优化”是主观的。大多数人更关心执行时间而不是可执行文件大小。因此,可以从不同的角度同时对这两个程序进行更多优化。
  • 使用一个函数代替另一个函数会增加程序中使用的函数总数。这可能会增加可执行文件的大小是合理的。

【讨论】:

  • 我认为这与一项操作与另一项操作需要多少指令无关。如果push_back(需要检查容量并在需要时扩展向量)与交换内部引用相比,需要更少 操作,我会感到惊讶。如果向量有很多元素,当然不会。我的猜测是 OP 已经在源代码的其他地方使用了push_back,所以move 增加了大小,而push_back 没有...
  • @DevSolar Certainly not if the vector has many elements 元素数量对程序中的指令数量没有影响,除非编译器完全展开循环,我认为这不太可能。
  • @DevSolar 另一点是有道理的;我已经修改了答案。
  • 是的,我在那边的赛道旁闲逛了一会儿。对不起。 ;-)
猜你喜欢
  • 2014-09-07
  • 2020-10-11
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2015-09-10
相关资源
最近更新 更多