我应该使用哪个C++stl容器
Which C++ stl container should I use?
想象一下以下需求:
测量数据应该被记录下来,用户应该能够遍历数据。
uint32_t timestamp;
uint16_t place;
struct SomeData someData;
在结构中有一个时间戳(
uint32_t
)、一个位置(uint16_t
)和一些数据具有恒定数量的数据集。如果新的来了,最老的就扔掉。
"位置"的数量是动态的,用户可以在运行时插入新的
应该可以通过数据迭代到下一个较新或较旧的数据集,但前提是位置是相同的
只需要在末端插入
应在程序启动时分配一次内存
插入不需要很快,但不应该长时间阻塞其他线程,这些线程可能正在遍历容器
内存需求应该是低
EDIT:-容器应该包含所有未使用的内存,因此它可能很大。
我不确定该用哪个容器。这是一个嵌入式系统,不应该使用升压等
我看到以下可能性:
std::vector-缺点:末尾的插入要求复制所有对象,在此期间,另一个线程无法访问vector。编辑:这可以通过将其实现为循环缓冲区来避免——请参阅下面的注释。在遍历向量时,我必须测试位置ID。也许将大量内存分配为一个块也可能是个问题,因为内存可能会被分割?
std::deque
-与std::vector
插入(和pop_back
)相比更快,但内存需求?如果插入在末尾,则迭代程序不会变为无效。但我仍然需要迭代和测试第二个ID("place")。我认为它不需要像向量或数组那样在一个大块中分配所有内存。如果在前面添加一个元素,在后面删除另一个元素(或者先删除后添加),我想不会进行内存分配吗?
std::queue
-我应该使用队列而不是deque?在许多实现中,队列确实是作为deque实现的吗?
std::map
-与deque一样,现有元素的任何迭代器都不会变得无效。如果我将密钥设置为位置和时间戳的组合,那么通过地图的迭代可能会更快,因为它已经排序了?地图的内存需求?
std::multimap
-由于位置的数量不是恒定的,我不能用"位置"作为索引进行多映射。
std::list
-在这里对德克没有优势吗?
一些人建议使用循环缓冲区。如果我不想把内存分配成一个大块,我仍然必须使用容器,上面的大多数问题都是有效的。
更新:我将使用这里建议的环形缓冲区,但使用deque作为底层容器。为了能够用预选的"位置"快速滚动数据集,我最终将在数据结构中引入两个额外的索引,它们将指向同一位置的上一个和下一个索引。
将使用多少内存?在我的特殊情况下,结构的大小是56个字节。gnu-lib使用512字节作为最小块大小,IAR编译器使用16字节。因此,所使用的块大小将分别为512或56字节。除了两个迭代器(每个迭代器使用4个指针)和大小之外,每个块还将存储一个指针。因此,在iar编译器(块大小为56字节)的实现中,与使用std::矢量或数组相比,(在32位系统上)将有7%的开销。在gcc实现中,块中将容纳9个对象(504个字节),而每个块需要512+4个字节,这增加了2%。
块大小不大,但指针数组所需的连续内存大小已经相对较大,尤其是对于一个块就是一个结构的实现。
std::列表每个结构需要2个指针,在我的32位系统中,这是14%的开销。
-
std::vector
。。。记忆可以被分割吗?
否,
std::vector
分配连续内存,如该链接中所述。数组也是连续的,但您也可以使用vector。 -
std::deque
是分段的,你说你不想要。还是要避免单个大的已分配块?目前还不清楚。无论如何,如果你真的想要一个循环缓冲区(因为你永远不会从前面/后面添加/删除元素),并且你无法控制块的大小,那么它对向量没有任何好处。
-
std::queue
。。。在许多实现中,队列确实是作为deque实现的吗?
是的,这是所有实现中的默认值。请参阅链接的文档或任何像样的书籍。
听起来你不想要FIFO队列,所以我不知道你为什么要考虑这个——接口不符合你的要求。
-
'std::map`
。。。通过地图的迭代可能更快,因为它已经排序了?
在大多数现代服务器/桌面架构上,map会更慢,因为推进迭代器涉及指针追逐(这会损害流水线)和可能的缓存丢失。您的匿名嵌入式架构可能对这些影响不太敏感,因此map对您来说可能更快。
。。。地图的内存需求?
更高。将节点大小(至少两个指针)添加到每个元素中。
- 在STL容器中使用模板类
- 检查函数返回类型是否与STL容器类型值相同
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 如果我真的真的想从 STL 容器继承,并且我继承构造函数并删除新运算符,会发生什么?
- 对象 C++ 向量的 STL 容器
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- 在 STL 容器的 STL 容器上调用 clear
- "迭代器"和"const_iterator"不是 STL 容器的必需成员?
- 删除包含包含动态对象的 STL 容器的智能指针
- C++:在子类中扩展静态 STL 容器/映射成员?
- ostream 运算符<< 为获取 STL 容器而过载,传递 std::string 会破坏它?
- 没有 STL 容器的迭代器
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 接受任何 STL 容器的函数
- C++ STL 容器中优先级搜索的优雅方法
- 我们如何打印出C++ STL 容器的value_type?
- 获取嵌套 stl 容器的大小(以字节为单位)
- 如何在C++中重新实现包含指针的 STL 容器的类的迭代器
- 迭代器和 STL 容器的关系
- 如何用索引增量generate_n填充STL容器