如何在选择不同类型的容器之间做出决定?

Posted

技术标签:

【中文标题】如何在选择不同类型的容器之间做出决定?【英文标题】:how to decide between choosing different types of containers? 【发布时间】:2014-08-12 16:11:08 【问题描述】:

我正在为运行 Linux 的嵌入式平台 (ARM11) 编写软件。该软件应该可以在不关闭/重新打开的情况下长时间(数月)工作,并且大多数嵌入式平台的 RAM 都很稀缺(操作系统和用户程序总共 250 兆字节)。该设备通过串行端口连接到另一台设备,它们以 ping 的形式连续(每 300 毫秒)一起通信,以了解状态、错误、警报等。该设备用于在人流量大的区域的门上进行门禁控制。数百人将使用 MIFARE 卡作为身份识别手段穿过它。我考虑过使用动态容器来保存保存通信数据包和卡数据的对象(因为它们的大小可以从几字节到一千字节不等)——当然,这些对象会不断地创建和销毁,它们不会停留很长一段时间(具有功能范围)。我选择的语言是 C++,我将使用 Qt 作为库。数据的所有元素也是无符号的 8 位字符。

使用这样的容器不会导致内存碎片问题吗? 既然容器的最大大小是已知的,那么使用 C 类型容器(如数组和结构)来获得更好的性能不是更好吗? 是否有选择合适容器的经验法则?

编辑: mifare 卡包含 1 千字节内存(1024 字节),分为 16 个扇区,每个扇区 4 * 16 字节块。在读取操作中,至少返回一个数据块,我需要从该块中提取低至一位的信息,我搜索从非接触式卡获得的数据的方式是通过提供给我的程序的参数文件阐明了卡片数据的映射和掩码。

【问题讨论】:

您认为 C++ 容器的具体缺点是什么(与原始 C 数组相比)? 1) 这取决于您如何使用它们。如果你明智地使用std::vector,你不会得到比使用C 动态分配数组更多的碎片。 2) 不,见 1)。 3)除非你真的需要别的东西(通常你不需要),否则使用vector。当然,如果你知道容器在编译时的大小,并且它们并不大,你可以考虑@ 987654322@ 而不是 std::vector @OliCharlesworth C++ 容器在内存操作上的成本更高,而且通常更慢。此外,如果不注意内存碎片,可能会导致我的软件停止工作或消耗所有内存。 @MoKi:你确定吗?访问std::vector 应该与原始数组相同。 我知道最大尺寸(因为这是硬件限制的问题),但最小尺寸未知。多大才算大? 【参考方案1】:

在这些情况下的主要挑战是内存碎片。一个主要原因是在分配中混合对象大小,并在不同时间释放它们。有有效的技术来解决这个问题。

对于初学者,如果您有许多固定大小的小对象(例如 28 个),那么针对该大小对象的专用分配器会有所帮助。它本身不会导致真正的碎片,你只有一个空闲块的位图,你可以选择第一个空闲块来分配。

对于字符串,将它们的大小四舍五入是有意义的,例如为 2 的倍数,然后用 \0 填充数据。然后,您可以使用大小为 8/16/32/64/等的专用分配器。您将浪费不超过 100%,实际上它接近 40%(取决于字符串长度分布)。对于短字符串,使用小字符串优化 - 检查 std::string 和/或 QString 是否使用它,如果不使用您自己的字符串类型可能是可取的。

诸如malloc'ed 数组之类的C 类型容器通常性能很差,正是由于上述原因:太容易以任何随机长度生成它们。 std::vector 通常以固定的增量增长。但是,请检查它是否将 reserve 请求四舍五入到合理的数量(2 的幂或 4KB 的倍数,以较小者为准)。如果没有,你应该这样做。

【讨论】:

以上是关于如何在选择不同类型的容器之间做出决定?的主要内容,如果未能解决你的问题,请参考以下文章

Drupal Views 如何在具有相同路径的多个显示器之间做出决定

Jenkins 如何在保留构建的天数和要保留的最大构建数量之间做出决定?

如何在 API 的 RPC 和 REST 之间做出决定?

如何在使用消息传递(例如 RabbitMQ)与使用 Web 服务进行后端组件交互/通信之间做出决定?

如何在开发 Web 应用程序和桌面应用程序之间做出决定 [关闭]

如何在 Hibernate 和 JDBC 之间进行选择?