为什么解析 YAML 比等效/更大数量的 JSON 慢?

Bos*_*ell 1 python json yaml

就在两个小时前,我启动了这段代码:

python -c "import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)" < input.yaml > output.json
Run Code Online (Sandbox Code Playgroud)

我有一个 450 MB 的 YAML 文件,在我使用 2 MB 的 YAML 测试文件来测试代码(在互联网上找到的代码)之前,这种转换浪费的时间真的令人难以置信(实际上仍在转换)。我收到了一个 9 MB 的转换后的 JSON 文件。这对我来说真的很奇怪(JSON 需要更多空间),但奇怪的是 python 打开 2 MB YAML 文件比打开 9 MB 的 JSON 文件浪费更多的时间。JSON 文件会立即打开,而 YAML 文件需要 2 分钟。有人可以解释这些事情吗?python、JSON 和 YAML 解析器背后的魔法在哪里?

Ant*_*hon 6

YAML 比 JSON 复杂得多,因此在解析 YAML 期间必须进行更多检查,例如下一个节点是否在输入时从块切换到流样式。更多的努力只是需要更多的时间。

因此,即使您使用 CLoader 加载(在 YAML 中您必须明确执行,并且这是该 JSON 标准库的默认设置),您的速度也会变慢。

YAML 文件可以更小应该是显而易见的,因为它不需要 JSON 所需的(双)引号开销。但是读取文件不是花时间的地方,而是解析,这对 YAML 来说更难。

YAML 解析器(纯 Python 和 CLoader 的帮助)比 JSON 解析器有更多的内存开销,分配内存当然也是有代价的。如果加载 2Mb YAML 文件使用 100Mb+ 内存,我不会感到惊讶。

当然,为较小的语法优化解析器也更容易,YAML 的 CLoader 肯定可以改进,但这样做需要很多时间。

还有一个区别是,即使使用json.load(),整个文件也会被读入内存然后被解析(load(),只是loads()在后台调用)。YAML 解析流,原则上可以处理大于内存/交换空间的文件,但也有一些开销。另一方面,解析 YAML 有相当多的开销,因此大文件也将成为一个问题。