【问题标题】:C++ - STL vector questionC++ - STL 向量问题
【发布时间】:2011-03-07 06:31:33
【问题描述】:

有什么方法可以让std::vectorreserving + resizing 上更快?

我希望获得与普通 C 数组相当的性能。

查看以下代码sn-ps:

TEST(test, vector1) {
   for (int i = 0; i < 50; ++i) {
      std::vector<int> a;
      a.reserve(10000000);
      a.resize(10000000);
   }
}

TEST(test, vector2) {
   for (int i = 0; i < 50; ++i) {
      std::vector<int> a(10000000);
   }
}

TEST(test, carray) {
   for (int i = 0; i < 50; ++i) {
      int* new_a = new int[10000000];
      delete[] new_a;
   }
}

前两个测试要慢两倍(4095 ms vs 2101 ms),很明显,这是因为std::vector 将其中的元素归零。 关于如何避免这种情况的任何想法?

或者可能有一些标准的 (boost?) 容器实现了一个固定大小和基于堆的数组?

谢谢

【问题讨论】:

  • 为了让测试做同样的工作,carray 测试需要一个for(std::size_t idx=0; idx&lt;10000000; ++idx) new_a[idx]=0;。一旦进入,我怀疑你会发现重大变化。
  • 我建议使用分析器,并且仅在性能低的情况下进行优化。上述代码可能不会出现在普通应用程序中。你通常不会做这样的事情。可能最好的方法是创建自己的数组类以获得更多控制权。
  • @Iulian:这是我希望能够对 cme​​ts 投反对票的 cmets 之一。你到底为什么要创建自己的数组?你真的尝试过实现std::vector吗?你会发现,想出一个既正确又快速的veryion是非常困难的。
  • @sbi 这样的“基准”在我看来是无关紧要的。这就是为什么必须在实际应用程序上进行测试而不是进行此类基准测试的原因——它可能会导致性能是 OK 事件与“慢”std::vector。如果他在这些地方发现性能问题,那么他可以考虑重写 std::vector 中使用的部分以减少 CPU 周期的浪费。此外,我相信上面的代码不太可能存在于 真实 应用程序中。我的原则是先让它发挥作用,然后让它更好/更快。
  • @lulian:这是一个很好的原则。但是@sbi 在这里完全符合要求。 stl 是一个经过深思熟虑、精心设计的库(如果使用得当),它的性能几乎与它们令人讨厌的 C 对应物一样好。创建您自己的数组类将导致花费在调试上的时间比在代码库的整个生命周期中可能节省的时间更多。

标签: c++ performance arrays vector


【解决方案1】:

当然,前 2 次测试速度较慢。他们明确地遍历整个向量并在每个元素上调用“int()”。编辑:这具有将所有元素设置为“0”的效果。

请尝试预订。

在我不久前提出的这个问题中,有一些与您的问题非常相关的信息:

std::vector reserve() and push_back() is faster than resize() and array index, why?

【讨论】:

  • 正确,carray 版本与矢量对应部分的作用不同。 std::vector::reserve() 是这里的答案
【解决方案2】:

boost::array

【讨论】:

  • 不幸的是,它是基于堆栈的,例如,您甚至无法在不更改堆栈大小的情况下分配 100 万个整数的巨大数组。
  • std::auto_ptr&lt;boost::array&lt;int&gt;&gt; 可以完成这项工作。
  • @HardCoder1986:如果你想要一个基于堆的数组,std::vector 就是你想要的。修正你的测试,你会发现它和手动摆弄动态分配的 C 数组一样快。
【解决方案3】:

您的测试是在调试模式还是发布模式下执行的?我知道 microsoft 编译器添加了很多调试检查,这些检查确实会降低性能。

【讨论】:

    【解决方案4】:

    也许您可以使用boost::scoped_array,但如果这确实对性能至关重要,也许您应该尝试以某种方式将初始化/分配放在最内层循环之外?

    【讨论】:

      【解决方案5】:

      我将为您提供疑问,并假设您已经进行了一些分析并确定以这种方式使用矢量作为热点。如果不是,那么考虑这些差异还为时过早,除非您在一个非常紧凑的小规模应用程序中工作,在这种情况下,每个时钟周期都很重要,在这种情况下,使用分析器更容易,并且有同样多的理由去做所以。

      boost::scoped_array 是一种解决方案。没有办法让向量不初始化它存储的元素。如果您不需要连续的内存块,另一个是 std::deque 。 deque 可以比 vector 或具有与其创建的元素数量相同的动态分配的数组快得多,因为它创建的内存块更小,操作系统倾向于更好地处理这些内存块并且对缓存友好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-10
        相关资源
        最近更新 更多