【问题标题】:Very fast serialization. Random access C++非常快的序列化。随机访问 C++
【发布时间】:2012-05-10 08:21:43
【问题描述】:

在 C++11 中,我可以使用什么来将数据快速序列化为多个文件(为避免数据冗余,我假设我会将数据拆分为多个表并根据其 ID 号连接它们)?

我考虑使用:

  1. 使用fstream.read()fstream.write() 访问的简单二进制文件。
  2. 使用mmap
  3. function google protobuf(如果我可以访问随机元素而不是遍历所有元素)。

所有表都将包含具有以下数据类型的列: uint8, uint16, uint32, uint64, string.

【问题讨论】:

  • 序列化和 I/O 是不同的东西。当您必须处理文件时,我不会太担心序列化速度本身..
  • 我的第一个想法是考虑SQLite
  • SQLite 不是一个选项,当我必须处理大量数据时(sqlite 文件大约有 8GB)。
  • @MiniKarol:我不知道 SQLite 的文件大小限制这么小。事实上,我很确定this is not true. 它说 1 Tera-pages 是默认的最大大小。而一个页面是几个字节;我不知道有多少,但如果是 1KB,那么最大文件大小就是 1024 Tera-bytes。

标签: c++ serialization c++11


【解决方案1】:

快速随机访问将是这里的挑战。实现这一目标的最简单方法是保持每一行的大小不变。使用protobufs 没有简单的方法可以做到这一点,除非您假设一个保守的最大尺寸。使用前两个选项中的任何一个都应该相对容易做到这一点(假设您对字符串的大小有合理的限制)。

但是,您可以任意变得更复杂。使用protobufs 可能会比简单的序列化使用更少的空间,因此您将有剩余的内存来构建索引。即使是相对较小的索引(例如,从表行号映射到每 100 行的文件偏移量)也会为您提供快速随机访问并使用更少的空间。当然,这比简单的每行大小相同的方法要复杂得多。

【讨论】:

    【解决方案2】:

    将数字和字符串存储分开。

    稀疏表、数值数据

    对数字类型的列使用列存储。列存储不存储 NULL 值,并提供连接逻辑允许您重现表行。

    不是单查找随机访问,但空间权衡可能会获胜,特别是如果列存储的索引保留在内存中。

    密集表、数值数据

    MMAP 一个文件用于读取。以恒定的宽度逐行存储数据。您可能需要调整文件打开参数以获得所需的缓存和预读优势。

    使用 fstream.write() 进行写作可能更快。

    字符串数据

    根据您的建议,听起来您的设计允许一次写入所有表,然后从该点开始执行只读随机访问。如果是这样,请查看Google's SSTable。它是一个存储层,可为可变长度数据提供有效的随机访问。

    【讨论】:

      【解决方案3】:

      MIT 许可的序列化库 Cap’n Proto 可能会提供您需要的功能。它由 Google Protobuf Kenton Varda 的主要作者编写。

      来自他的quoteCap'n Proto 使用指针来支持完全随机访问。这意味着您可以执行诸如 mmap() 一个巨大文件并拉出一个内部对象之类的事情,而无需实际处理整个事情,或者以与编写顺序不同的顺序访问子对象

      您提到的数据类型(uint8、uint16、uint32、uint64、字符串)都被Cap'n Proto Schema Language支持

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-08
        • 2016-06-06
        • 1970-01-01
        • 2011-06-16
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        相关资源
        最近更新 更多