我应该使用哪个C ++ stl容器?

时间:2018-06-25 08:44:36

标签: c++ dictionary thread-safety containers deque

想象一下以下要求:

应该记录测量数据,并且用户应该能够遍历数据。

uint32_t timestamp;
uint16_t place;
struct SomeData someData;
  • 在结构中具有时间戳记(uint32_t,位置(uint16_t)和一些数据

  • 具有恒定数量的数据集。如果有新的,最旧的被扔掉。

  • “位置”的数量是动态的,用户可以在运行时插入新的

  • 应该有可能遍历数据到下一个新的或更旧的数据集,但前提是位置相同

  • 仅需在末尾插入

  • 内存应在程序启动时分配一次

  • 插入不必很快,但不应长时间阻塞可能正在容器中迭代的其他线程

  • 内存需求应该低

编辑:-容器应存储否则不使用的所有内存,因此它可能很大。

我不确定应该使用哪个容器。这是一个嵌入式系统,不应使用boost等。

我看到以下可能性:

std :: vector-缺点:最后插入需要复制所有对象,在此期间,另一个线程无法访问该向量。编辑:这可以通过将其实现为循环缓冲区来避免-参见下面的注释。当遍历向量时,我必须测试地点ID。将一个内存分配为一个块也许也可能是一个问题-因为内存可以分段?

std::deque-与std::vector插入(和pop_back)相比更快,但是需要内存吗?如果插入在末尾,则迭代器不会变得无效。但是我仍然必须迭代并测试第二个ID(“位置”)。我认为不需要像矢量或数组那样在一个大块中分配所有内存。如果在前面添加一个元素,然后在末尾删除另一个元素(或先删除然后添加),我猜是否没有发生内存分配?

std::queue-我应该使用队列而不是双端队列?确实在许多实现中,队列生成器就像双端队列一样受到威胁吗?

std::map-像双端队列一样,现有元素的任何迭代器都不会失效。如果我将键组合为位置和时间戳,那么遍历地图的迭代速度可能会更快,因为它已经排序了?地图的内存需求?

std::multimap-由于位数不是恒定的,因此我无法以“ place”作为索引来制作多图。

std::list-在这里比双端队列没有优势吗?

有人建议使用循环缓冲区。如果我不希望将内存分配为一个大块,我仍然必须使用容器,并且上面的大多数问题仍然有效。

更新: 我将按照此处的建议使用环形缓冲区,但使用双端队列作为基础容器。为了能够快速滚动带有预选“位置”的数据集,我最终将在数据结构中引入两个附加索引,这些索引将指向具有相同位置的上一个和下一个索引。

将使用多少内存?在我的特殊情况下,该结构的大小为56个字节。 gnu lib使用512字节作为最小块大小,IAR编译器使用16字节。因此,使用的块大小将分别为512或56个字节。除了两个迭代器(每个使用4个指针)和大小外,每个块还将存储一个指针。因此,与使用std :: vector或数组相比,在iar编译器(块大小为56字节)的实现中,开销(在32位系统上)为7%。在gcc实现中,该块中可容纳9个对象(504字节),而每个块需要512 + 4字节,这要多2%。

块大小不大,但是指针数组所需的连续内存大小已经相当大,尤其是对于其中一个块是一个结构的实现。

一个std :: list每个结构将需要2个指针,在我的情况下,在32位系统上,这是14%的开销。

1 个答案:

答案 0 :(得分:0)

  1. std::vector

      

    ...内存是否可以分段?

    否,std::vector分配连续的内存,如该链接中所述。数组也是连续的,但是您也可以使用向量。

  2. std::deque是分段的,您说过不需要。还是要避免分配单个大块?还不清楚。

    无论如何,如果您真的想要一个圆形缓冲区,它比矢量没有任何好处(因为无论如何您永远都不会从前/后添加/删除元素),并且您无法控制块的大小。

  3. std::queue

      

    ...在许多实现中,队列是否像双端队列一样被设置为真的?

    是的,这是 all 实现中的默认设置。请参阅链接的文档或任何体面的书。

    听起来好像不想要FIFO队列,所以我不知道为什么要考虑这个队列-接口不符合您的要求。

  4. 'std::map`

      

    ...通过地图迭代可能更快,因为它已经排序了?

    在大多数现代服务器/桌面体系结构上,映射将较慢,因为推进迭代器会涉及指针追逐(这会损害流水线操作)和可能的高速缓存未命中。您的匿名嵌入式体系结构 可能对这些影响不太敏感,因此地图 可能对您更快。

      

    ...地图的内存需求?

    更高。您已将节点大小(至少两个指针)添加到每个元素。