【问题标题】:Matrix/Vector initialization performance矩阵/向量初始化性能
【发布时间】:2020-11-09 09:44:25
【问题描述】:

这更像是一个教育问题,我没有要解决的具体问题。我想了解以下场景中“幕后”发生的事情:

我们有 2 个ints、wh,我们需要一个 0s 的矩阵 (vector<vector<int>>)。有多种方法可以做到这一点,我想知道哪一种表现最好(可能这意味着哪一种表现最少)。

选项 1:

vector<vector<int>> m;

for (int i = 0; i < h; i++)
{
    m.push_back(vector<int>());
    for (j = 0; j < w; j++)
        m[i].push_back(0);
}

选项 2:

vector<vector<int>> m;

for (int i = 0; i < h; i++)
    m.push_back(vector<int>(w, 0));

选项 3:

vector<vector<int>> m(h, vector<int>(w, 0));

m.push_back(vector&lt;int&gt;());/m.push_back(vector&lt;int&gt;(w, 0)); 处的临时值是否在内存中创建,然后也复制到m 中?如果不是最好使用选项 1 来最小化复制? (假设我们只讨论更大的数组,比如 1,000,000 x 1,000,000)。选项 3 也面临同样的困境;哪个往往更快(至少在纸面上),为什么会这样?

【问题讨论】:

  • 根据 hw 的值,选项 1 和 2 中的向量可能会处理许多内存重新分配。在选项 3 中没有重新分配。对于第一个和第二个选项,push_back 将导致临时向量被 移动 并且不被复制(但仍然会有重新分配)。作为改进选项 1 和 2 的一种方法,请改用 emplace_back。但“最好”的方式(显示的三个)是选项 3。
  • 您提到“副本”,但您认为哪个示例有副本?为什么你认为这很糟糕?

标签: c++ memory memory-management


【解决方案1】:

如果您想要 Matrix 类的性能,首先不要使用 std::vector&lt;std::vector&lt;T&gt;&gt;。您编写了一个封装一维std::vector&lt;T&gt; 的适当类。一个向量的向量在内存中被分片。

如今,在商业硬件上,一万亿元素矩阵在技术上是可行的,但要初始化它,您真的非常需要多个线程。这是对您的 3 个示例的另一个实际反对意见。

话虽如此,对于小型实验,您的所有代码都可以。

【讨论】:

  • 正如问题中所述,给出的示例只是一个简单的示例,用于说明 STL 容器必须包含许多其他容器的一般问题,我想了解背后发生了什么场景。
  • @RaresDima:我的回答只是一个简单的例子,为什么“一般”问题在实践中实际上并不普遍。这些问题需要逐案解决,通常是在分析显示实际问题时。 C++ 开箱即用具有不错的性能,尤其是在 C++11 添加了移动操作之后。
猜你喜欢
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多