【问题标题】:What are the Issues with a vector-of-vectors?向量向量的问题是什么?
【发布时间】:2016-11-09 17:03:46
【问题描述】:

我读到vector-of-vectors 在固定的 2nd 维度下是不好的,但我无法在 http://www.stackoverflow.com 上找到问题的明确解释。

有人能解释一下为什么在单个vector 上使用二维索引比对固定的第二维使用vector-of-vectors 更可取吗? p>

另外,我假设vector-of-vectors 是具有可变 2nd 维度的二维数组的首选数据结构?如果有任何相反的证据,我很乐意看到。

【问题讨论】:

  • 只有剖析师才能认真回答这个问题。互联网上有很多不受支持的说法;牢记原则:先行其道;以后快点。总的来说,是什么让程序快速运行?好的算法,异步,局部性,技巧。按此顺序;将向量的向量更改为单个向量看起来像第三/第四步。
  • 给出的最常见原因是vector<vector<whatever> > 中的元素不连续,设置这样的向量需要更多工作(例如多次分配)。但是,这些论点是主观意见,而不是对事实的绝对陈述。哪种方法更好取决于如何测量/分析代码的行为/等。
  • 另见this ISO CPP 常见问题解答。
  • @LightnessRacesinOrbit 答案就在其中矩阵。 并继续详细说明两者。这怎么不是在说同一件事?
  • @NathanOliver:“重复”的意思是“问题是完全重复的”。不是“问题是模糊相关的,一些答案可能适用于两者”。在您对 this 问题的回答中,请随意交叉引用该页面。

标签: c++ matrix vector 2d dimensions


【解决方案1】:

对于std::vector,底层数组是从堆中动态分配的。如果你有例如std::vector<std::vector<double>>,那么你的外向量看起来像

{v1, v2, v3, v4, ... vn}

这个看起来就像每个内部向量都将在连续的内存中,而且它们会,但它们的底层数组不会是连续的。请参阅this post 中的内存布局图。换句话说,你不能这么说

&(v1.back()) + 1 == &(v2.front()) // not necessarily true!

相反,如果您将单个向量与 striding 一起使用,那么您将获得数据局部性,并且它本质上会更多 cache friendly,因为您的所有数据都是连续的。

为了完整起见,如果您的矩阵是稀疏的,我不会使用这些方法中的任何一种,因为 more elegant and efficient storage schemes 比直接的一维或二维数组要多。虽然你提到你有一个“固定的二维”,但我会假设这里不是这种情况。

【讨论】:

    【解决方案2】:

    我将用一个简单的类比来回答。

    在这两个方面,一般来说什么是“更好”?

    1. 电话簿,其中每个条目都是一个代码,指的是不同的书,您必须找到并阅读它才能发现某人的电话号码
    2. 列出人们电话号码的电话簿

    将所有数据保存在一个大 blob 中更简单、更合理,也更容易存储在计算机的缓存中。包含 N 个向量的向量在操作上要复杂得多(请记住,每个向量都需要动态分配和大小管理操作!);一个向量就是一个向量。您还没有将工作量乘以 N

    真正唯一的缺点是,要使用一维底层数据存储来模拟二维数组访问,您需要编写一个外观。幸运的是,这很容易。

    现在来说主观部分:总的来说,我认为这是值得的,除非您真的很着急并且您的代码质量并不特别重要。

    【讨论】:

      【解决方案3】:

      使用向量的向量:

      1. 由于分配了多个块,内存分配效率低下。
      2. 模拟锯齿状的右手边缘,因此虫子可以潜入。

      一般来说,使用单个向量会更好,因为内存管理更简单。但是,如果您的矩阵很大,您可能会遇到问题,因为很难获得一个大的连续块。

      如果您的数组是可调整大小的,那么我仍然会坚持使用单个向量:调整大小的复杂性可以隔离在您可以优化的单个函数中。

      当然,最好的解决方案是使用 Boost 中可用的线性代数库 (BLAS)。这也可以很好地处理大型稀疏矩阵。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-20
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 1970-01-01
        • 2012-09-04
        • 1970-01-01
        相关资源
        最近更新 更多