使用 yaml-cpp 解析 YAML 时的内存消耗

Posted

技术标签:

【中文标题】使用 yaml-cpp 解析 YAML 时的内存消耗【英文标题】:Memory consumption during parsing of YAML with yaml-cpp 【发布时间】:2014-05-18 17:43:19 【问题描述】:

我正在为内存有限的嵌入式系统开发 Qt 应用程序。我需要接收几兆字节的 JSON 数据并尽可能快地解析它,并且不占用太多内存。

我在考虑使用流:

JSON 源(HTTP 客户端)---> ZIP 解压器 ---> YAML 解析器 ----> 映射到数据库的对象

数据从网络到达的速度比我解析它的速度要慢得多。

    yaml-cpp 解析 1MB 数据需要多少内存? 我希望在创建映射到数据库的对象后立即释放来自解压缩器的原始数据和 YAML 解析器用于该数据的内部内存。有可能吗? yaml-cpp 是否支持异步解析?因此,一旦 JSON 对象被解析,我就可以将其存储在数据库中,而无需等待来自 HTTP 源的完整内容。

【问题讨论】:

你收到多少个对象?每个对象有多少属性?每个属性的平均大小?我的 yaml-cpp 能够在它们进来时一次解析一个对象?你收到的是 JSON 还是 YAML? 我可以收到几千个对象。它可以很容易地成为 7MB 的文本。我使用 JSON,它是 YAML 1.2 的一个子集,可以用 yaml-cpp 解析。我不知道 yaml-cpp 是否能够在它们进入时一次解析一个对象,因为这是我的问题的一部分:) 【参考方案1】:

由于您有内存限制并且您的数据已经在 J​​SON 中,您应该使用低内存 JSON 解析器而不是 YAML 解析器。试试jsoncpp - 虽然我不确定他们对流媒体的支持是什么(因为 JSON 没有文档的概念)。

yaml-cpp 为流设计的,所以如果有文档要解析但流仍然打开,它不会阻塞;但是,在 yaml-cpp 中有一个 outstanding issue,它一次读取多个文档,因此它确实不是为极低内存使用而设计的。

至于解析 1 MB 数据需要多少内存,大概在 3 MB 左右(原始输入流,加上解析后的流,再加上生成的数据结构),但它可能会因不同而有很大差异关于您正在解析的数据类型。

【讨论】:

你能推荐一些适合这个目的的 C/C++ 库吗?我在 Ubuntu 存储库中进行了快速搜索,但没有找到任何合适的东西。你能回答我的3个问题吗?根据您所说,我猜对 2 和 3 的回答是“否”。第一个问题怎么样? 我回来优化这块功能。我在解析之前和之后检查了我的进程的 VmPeak,结果发现 VmPeak 增加了 16MB。这个结果是用 84kB 的 gzip 压缩 JSON 文件实现的,解压后几乎 1MB。与这个 RapidJSON 原位解析相比,我增加了 3MB。

以上是关于使用 yaml-cpp 解析 YAML 时的内存消耗的主要内容,如果未能解决你的问题,请参考以下文章

使用 yaml-cpp 解析 YAML !!timestamp(日期时间)

尝试使用 yaml-cpp 解析 OpenCV YAML 输出

YAML 未解析的外部符号 (yaml-cpp)

使用 YAML-CPP 发出解析文件

如何使用 yaml-cpp 发出和解析原始二进制数据

yaml解析的方式? (yaml-cpp)