我是否应该认为静态副本的成本很高?

时间:2019-02-04 15:40:31

标签: c++ performance c++11

遍历集合时,说一个Point的向量,其中Point是保存xyz数据的某种结构或某物,当我需要一次将这些点转换为另一种类型的点时,我是否应该认为它像副本一样昂贵?

例如,如果我有一个vector<Point> v,我显然会尽量避免:

vector<OtherPointType> vo;
// populate v
std::transform(v.begin(), v.end(), vo.begin(),
   [](Point const& p) { return OtherPointType{p.x, p.y, p.z}; });
SomeOperation(vo); // Can only operate on vector<OtherPointType>

但是,这和这样做一样昂贵吗?

for_each(..., [](Point const& p)
{
   OtherPointType opt(p.x, p.y, p.z);
   SomeOperation(opt); // Can only operator on `OtherPointType`
});

我的直觉是,因为后者是没有任何动态分配的静态副本,所以它应该不昂贵,但我认为问这个问题很重要。

通常,在后一种情况下,我可以使用类似Eigen::Map之类的东西,但是即使在那儿,我仍然要写两个int(在栈上),我认为是由于Eigen::Stride(是在这种情况下,这甚至是一个好的解决方案?)但是然后,像CGAL这样的库就没有映射功能了,我很好奇与之合作的好方法。

请注意,我的工作通常每秒处理一百万个点,因此,我要尽量减少昂贵的副本,这一点很重要。

更新

在一个子问题中,我想知道Eigen::Map是否适合上述后一种情况:

我运行了一个benchmark,并且至少在gcc 5.4上,即使有1亿点,结果也难以接近。使用Eigen::Map vs 构造Eigen::Vector3d分别花费了276 ms和285 ms。尽管构建所需的时间更少,但是点数更少,这告诉我,区别在于不确定性内,计算机上运行的其他进程可能会产生更大的影响。

1 个答案:

答案 0 :(得分:4)

  

我应该认为[转换]和复制一样昂贵吗?

因为它是不同的操作,所以不一定。它可能或多或少地昂贵。但是,将其与副本进行比较是合理的。

  

但是[复制向量]和[迭代向量并将每个元素复制到自动变量中]一样昂贵

可能不是。

  

我的直觉是,因为后者是没有任何分配的静态副本,所以它不应该昂贵

这就是为什么后者可能不比前者贵的原因。但是后者是否昂贵取决于上下文。仍然是线性渐进复杂度的运算,因此如果向量很大,则与副本相比,分配可能微不足道。

某些东西是否比硬件上的其他东西要贵,以及某些东西在程序上下文中是否很昂贵,您可以尝试使用探查器来查找。