【问题标题】:Is a vector more appropriate in my case - C++在我的情况下,向量是否更合适 - C++
【发布时间】:2012-01-21 03:43:19
【问题描述】:

我在 Stack Overflow 和其他地方读到向量比数组的读写速度更快。我的程序有一个有趣的问题,我正在读取的文件包含许多不同类型的片段,但在我阅读它们之前我不知道每种类型有多少片段。因此,例如,如果片段 1 可以通过

struct frag_1
{
    int number1;
    int number2;
};

我已经遍历文件一,计算每个片段类型出现的次数,分配类型为片段结构的内存数组,就像示例结构一样,然后我填充并操作它们。

看起来向量的读写速度要快得多,动态的我可以随时添加到它们中,而且通常是更好的实践。

这是真的吗?谢谢。

【问题讨论】:

  • “我在 Stack Overflow 和其他地方读到向量比数组的读写速度更快。” 我非常怀疑这个说法的真实性。充其量只是一个微优化。
  • 充其量是完全错误的。 :-)
  • 您能详细说明一下吗?我看到一些基准表明向量确实更快。
  • @SatchmoBrown:这是不可能的,因为向量在下面使用数组...
  • @SatchmoBrown:向量通常使用一个数组来实现,因此从逻辑上讲,只能执行得快或慢。然而,向量提供的便利通常大大超过读/写性能的通常微小差异。我很想看到这个基准声称向量更快。

标签: arrays performance vector


【解决方案1】:

实际上,对于这种模式,deque 通常是最佳选择。为此目的使用vector,除非您至少可以大致猜测最终大小,否则将需要大量的分配/复制/释放周期,因为实现使用的向量太小。

【讨论】:

  • 向量中没有的双端队列有什么优势。我喜欢双端队列元素可以通过索引访问的事实。此外,我们在这里猜测大小时所说的范围是什么。我假设您在谈论储备功能,因此没有大量的重新分配,但假设在此示例中,我选择了 200,实际大小为 450。我可以期待什么样的性能影响?
  • 你可以做两件事之一。您可以从一开始就选择最佳结构,或者除非您遇到性能问题,否则您可以不用担心它。您似乎试图以某种奇怪的方式区分这两种策略之间的差异。扩大向量将需要分配/复制/解除分配。扩大双端队列不会。命中的多少将取决于实现的细节和访问模式。如果您选择双端队列,则不必担心。
  • @DavidSchwartz:你如何认为扩大双端队列不会需要分配/复制/解除分配,而不依赖于特定的实现?
【解决方案2】:

您似乎在这里有两个对象列表:片段本身,以及 number1number2 作为这种特定类型片段的成员。

首先,片段本身。根据您的描述,请使用std::vector,特别是如果您事先不知道您将拥有多少个片段。 (你说的。)它会为你分配内存,并大大减少错误的变化,这大大超过了你自己做的任何(非常微小的)速度改进。

关于成员,请考虑:

struct frag_1
{
    int numbers[2];
};

(另外,请考虑更好的变量名称,因为这可能会让您(或我们)对哪个“更好”有更明确的答案。)

请注意,我只考虑了向量与数组供您使用。如果您稍后需要通过某个成员查找某个片段,那么某种类型的映射类型可能更合适。如果您只是加载和循环遍历所有片段(并全部使用它们),那么 std::vector 在大多数情况下通常都可以。


关于std:vectors 调整大小期间的性能:如果您知道向量的最终大小,您可以提前告知向量。如果您不知道最终大小,那么您就不知道,并且可能会发生大小调整和内存分配无论容器如何。大多数容器,即使发生重新分配,也会提供 O(n) 性能。您要问的问题以及其他帖子似乎暗示的是resize 将成为您的瓶颈。所以:个人资料。向量很可能会完成工作,并且做得足够快,以至于您不会关心调整大小。如果您从磁盘读取内容,仅磁盘 I/O 本身通常会大大超过调整大小操作,因此优化它们毫无意义。

【讨论】:

  • 有人说不知道近似大小会影响性能(我认为他们指的是储备功能)会扼杀性能。你说什么?
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2011-04-17
  • 1970-01-01
相关资源
最近更新 更多