YAML和JSON之间有什么区别?

932
YAML和JSON之间有哪些区别,特别是考虑以下几点?
- 性能(编码/解码时间) - 内存消耗 - 表达清晰度 - 库的可用性和易用性(我更喜欢C语言)
我打算在我们的嵌入式系统中使用其中之一来存储配置文件。

51
请注意,JSON可以被视为YAML的子集:http://en.wikipedia.org/wiki/JSON#YAML - Charles
2
@Charles,是的,但它们有一些微妙的差别:http://ajaxian.com/archives/json-yaml-its-getting-closer-to-truth - pierrotlefou
2
由于YAML(大约)是JSON的超集,因此在不知道是否使用其表达能力的情况下无法回答性能问题。如果您不需要它:YAML解析器读取JSON有多快?如果确实需要它:当您考虑到可能更长的JSON表示相同想法时,JSON解析器会慢多少? - poolie
不是在宣传,但我曾看到一些非常简单的Lua数据格式。 - nawfal
11
YAML文档有时会很复杂且难以阅读。使用YAML存在“Billion laughs”攻击的风险。但另一方面,复杂对象、图形和其他结构可以在YAML中高效地序列化。对于交换格式和简单结构,首选JSON。而对于复杂对象序列化或语法定义,则可能更喜欢使用YAML。 - Erik Aronesty
显示剩余4条评论
15个回答

801

在技术上,YAML是JSON的超集。这意味着,理论上至少,YAML解析器可以理解JSON,但不一定反过来。

请参阅官方规范,在标题为"YAML: Relation to JSON" 的部分。

总的来说,有些我喜欢YAML而在JSON中不可用的东西。

  • 正如@jdupont指出,YAML在视觉上更易于查看。事实上,YAML官网本身就是有效的YAML,但易于人类阅读。
  • YAML具有使用“锚点”引用文件中其他项的能力,因此它可以处理关系信息,就像在MySQL数据库中找到的那样。
  • YAML更强大,可以嵌入其他序列化格式(如JSON或XML) YAML文件中。

实际上,对于您或我所做的事情,这最后两点都不太重要,但从长远来看,我认为YAML将是一个更强大和可行的数据序列化格式。

现在,AJAX和其他Web技术倾向于使用JSON。YAML目前更多地用于离线数据处理。例如,默认情况下包含在基于C的OpenCV计算机视觉软件包中,而JSON则不是。

您将找到JSON和YAML的C库。 YAML的库往往较新,但我过去没有遇到任何问题。请参见Yaml-cpp等示例。


246
JSON虽然非常接近,但并不是YAML的子集,在使用中会遇到令人恼火的不兼容问题。JSON库通常更快...(参考链接:https://dev59.com/yHE95IYBdhLWcg3wHqIV)。YAML的支持者会坚称它是JSON的子集。如果可读性很重要,请使用YAML;如果兼容性和速度很重要,请使用JSON。 - Erik Aronesty
13
YAML 是 JSON 语法的一个超集。也就是说,如果您使用与 YAML 兼容的方式使用 JSON,则它是一个适当的子集。就像上面 pierr 发表的评论一样,规范旨在实现兼容性。 - naught101
175
YAML 支持注释,这很方便。 - Den
76
JSON曾经接近于YAML 1.1的一个子集,但自从YAML 1.2版本以后,JSON现在是它的真正子集。YAML 1.2主要发布是为了解决两种规范之间最后几个不兼容的问题。 - 00prometheus
91
根据YAML 1.2规范:“此次修订的主要目标是将YAML与JSON对齐,成为官方子集。” - Rich C
显示剩余8条评论

274

差异:

  1. 根据使用方式不同,YAML 可能比 JSON 更易读
  2. JSON 通常更快速,可能与更多系统互操作
  3. 可以很快地编写一个“足够好”的 JSON 解析器
  4. 重复键在 JSON 中是潜在有效的,但在 YAML 中绝对无效。
  5. YAML 具有许多功能,包括注释和关系锚点。因此,YAML 语法相当复杂,难以理解。
  6. 可以在 yaml 中编写递归结构:{a: &b [*b]},这在某些转换器中会无限循环。即使有循环检测,仍然可能存在“yaml 炸弹”(请参见xml bomb)。
  7. 由于没有引用,因此无法在 JSON 中序列化具有对象引用的复杂结构。因此,YAML 序列化可能更有效率。
  8. 在某些编程环境中,使用 YAML 可能允许攻击者执行任意代码

观察结果:

  1. Python程序员通常非常喜欢YAML,因为使用缩进而不是括号语法来表示级别。
  2. 许多程序员认为将“意义”附加到缩进是一个糟糕的选择。
  3. 如果数据格式将离开应用程序环境,在UI中解析或在消息层中发送,则JSON可能是更好的选择。
  4. YAML可以直接用于复杂任务,如语法定义,并且通常比发明新语言更好。

13
没问题。Yaml 1.2 的整个目的就是解决少量兼容性差异,使得 JSON 成为其严格子集。如果您认为该规范没有实现其目的,Erik,请指出一个违反 YAML 规范和/或破坏经过验证的1.2兼容 YAML 解析器的有效 JSON 示例。 - SFEley
39
YAML规范指出,可能存在一些在JSON格式下合法但在YAML格式下不合法的文件,但实际使用中这种情况并不常见。"JSON的RFC4627要求映射键仅需“应该”是唯一的,而YAML则坚持要求它们“必须”是唯一的。从技术上讲,YAML符合JSON规范,选择将重复项视为错误。实际上,由于JSON对这些重复项的语义是沉默的,因此唯一可移植的JSON文件是具有唯一键的文件,这些文件也因此是有效的YAML文件。" - http://www.yaml.org/spec/1.2/spec.html#id2759572 - David C. Bishop
12
对于缩进的使用,我认为可能需要适应,并不是每个人都会喜欢它。例如,我是一个.NET程序员。我正在查看一个travis.yml文件,想知道为什么会出现问题。后来我发现我在某个位置使用了制表符,而不应该这样做。并不是每个人都习惯于由于空格/制表符/换行符偏好而导致程序出错。 - Phil
12
标签作为缩进字符是不被允许的。在所有编程语言中,这都是很好的编码风格,无论是否使用语法缩进。 - 00prometheus
9
@Wyrmwood 我个人喜欢使用 Python 和 YAML ,并且每天都在使用它们。我倾向于使用 YAML 来处理需要经常编辑的内容,而使用 JSON 来处理那些“可能”需要查看的内容。我曾受到 C++ 开发人员的有效批评,他们认为缩进很令人困惑...特别是在存在多层级或较长函数块时。当然…好的可测试代码不会有这些问题,所以通常不是问题。这是我的个人观察,但任何随意的谷歌搜索都会产生许多结果……所以这很容易验证。 - Erik Aronesty
显示剩余7条评论

121

绕过深奥的理论

这个标题回答了问题,但大多数人只是从谷歌搜索结果中读取标题,所以我认为有必要从网页开发者的角度进行解释。

  1. YAML使用空格缩进,这对于Python开发人员来说是熟悉的领域。
  2. JavaScript开发人员喜欢JSON,因为它是JavaScript的子集,可以直接在JavaScript中解释和编写,同时使用一种简写方式声明JSON,在使用典型变量名称而不带空格的情况下,无需双引号键。
  3. 有大量的解析器在所有语言中都非常适用于YAML和JSON。
  4. 在许多情况下,YAML的空格格式更容易查看,因为格式需要采用更具人类可读性的方法。
  5. 尽管YAML的形式更紧凑、更易于查看,但如果您的编辑器中没有可见的空格格式,则手动编辑可能会出现误差。制表符不是空格,因此如果您没有编辑器将您的按键转换为空格,则会进一步混淆。
  6. 由于要检查的功能比YAML少得多,因此JSON的序列化和反序列化速度要快得多,这使得处理JSON的代码更小、更轻。
  7. 一个常见的误解是YAML需要比JSON更少的标点符号并且更紧凑,但这是完全错误的。空格是不可见的,所以似乎字符更少,但如果您计算实际必须存在的空格以使YAML正确解释并具有适当的缩进,则会发现YAML实际上需要比JSON更多的字符。JSON不使用空格来表示层次结构或分组,并且可以轻松地压缩,去除不必要的空格以进行更紧凑的传输。

房间里的大象:互联网本身

JavaScript在Web领域中占据着绝对的主导地位,JavaScript开发人员普遍偏爱使用JSON作为数据格式,并且与流行的Web API一起使用,因此在一般意义上进行Web编程时,很难争辩使用YAML而不是JSON,因为在团队环境中你可能会被否决。事实上,大多数Web程序员甚至不知道YAML的存在,更不用考虑使用它。

如果你正在进行任何Web编程,JSON是默认选择,因为在使用JavaScript时不需要进行翻译步骤,所以在这种情况下,你必须提出更好的理由来使用YAML而不是JSON。


22
我不同意Python开发者更喜欢YAML。Python的字典基本上就是JSON,字典的列表也基本上是JSON格式的。Python内置了json库。另外一提,我是Python开发者,我更喜欢JSON(我认识的大多数Python开发者也更喜欢JSON)。 - karantan
8
关于空格的一件事情真正让我困扰的是,很容易混淆并搞错缩进是否嵌套或在同一级别,如果没有指南规则,也很容易犯错误。这就像编辑 YAML 时没有人会提及的隐藏的“哎呀,这真的不那么容易”的情景。在 JSON 中从未遇到过这样的问题。 - King Friday
9
@JasonSebring. 你会想知道为什么YAML选择使用空格。我的第一次涉足YAML导致了一个崩溃的应用程序……全部都是因为空格。你本以为使用缩进而不是非打印字符可能更有意义!(也就是说,为什么他们不选择"."而不是" "?)要理解YAML,必须查阅规范。要理解JSON则不需要这样做。(我已经去过前者,从未去过后者)。对我来说,这表明这种格式并不真正“人类可读”。 - cmroanirgo
13
是的,这也是我的经历。我的老板强迫我们使用 YAML 而不是 JSON,这使得编辑和摄入变得不必要地糟糕。我写这篇文章就是为了这个原因,希望能得到支持票来证实我的想法。 - King Friday
6
作为一个更多时候会黑客攻击而不是从头开始创造东西的普通IT人员,对我而言,能够以人类可读的方式编写代码,并且在多个IDE和平台上也能够轻松阅读,无需担心空格如何呈现,这是非常宝贵的。因此,在我看来,所谓的空格天生易读性的说法并不完全正确。我又有点晕了,糟糕。 - mmseng
显示剩余10条评论

72

这个问题已经6年了,但奇怪的是,没有一个答案真正回答了所有四个方面(速度、内存、表现力、可移植性)。

速度

显然这取决于实现方式,但由于JSON被广泛使用,并且很容易实现,因此它倾向于获得更多本机支持和更快的速度。考虑到YAML可以做JSON的所有事情,再加上一大堆其他功能,任何可以进行比较的两者实现中,JSON的实现很可能会更快。

然而,考虑到YAML文件可能比其JSON对应文件略小(由于较少的",字符),在特殊情况下,高度优化的YAML解析器可能更快。

内存

基本上相同的论点适用。如果它们表示相同的数据结构,很难看出为什么YAML解析器会比JSON解析器更节省内存。

表现力

正如其他人指出的那样,Python程序员倾向于喜欢YAML,JavaScript程序员倾向于JSON。我会发表以下观察:

  • 很容易记忆JSON的整个语法,因此非常自信地理解任何JSON文件的含义。YAML没有被任何人真正理解过。其微妙之处和边缘情况的数量是极端的。
  • 由于很少有解析器实现了整个规范,即使在给定上下文中,也更难确定给定表达式的含义。
  • JSON中缺少注释,在实践中确实很痛苦。

可移植性

很难想象一个现代语言没有JSON库。也很难想象JSON解析器不实现完整规范。YAML得到了广泛的支持,但不如JSON普及,并且每个解析器都实现了不同的子集。因此,YAML文件比你想象的不太互操作。

总结

JSON在性能(如果相关)和互操作性方面是最好的,适合机器读取。YAML更适合人类维护的文件。 HJSON 是一个不错的妥协选择,但可移植性大大降低。 JSON5 是一个更为合理的妥协,具有明确定义的语法。


7
我曾以为YAML更小,因为有些看不见的字符欺骗了我。看不见 => 不存在,实际上不是这样的。如果你要算上那些必须存在的看不见的字符,特别是在YAML越来越大的嵌套中,它很快就会超过JSON的大小。我觉得这非常有趣,因为大多数人都被它的可读性所欺骗,直到我真正思考它时才明白,你可以展开JSON和YAML,但YAML不太行。我还发现YAML很难手动编辑,不是阅读,只是编辑需要打开编辑器指南,有时会误解嵌套项。 - King Friday
7
我感觉这里没有明确表述:对于设置/配置文件,YAML更好(出于大家上面提到的原因)。对于机器/机器之间的互操作使用JSON。换句话说,如果你的目标受众是人类,那么YAML更好。如果目标是另一个程序(但你仍然希望数据能够被人类阅读),请使用JSON。 - Florin T.
没错,但问题提出了一些非常具体的参数,关于他们想要如何比较这两个。就我个人而言,我永远不会使用YAML做任何事情。我要么使用JSON进行互操作性,要么使用JSON6进行人工维护。 - Steve Bennett
1
实际上,为了优化这一点:对于NodeJS项目的配置文件,我通常更喜欢使用纯JavaScript而不是JSON。它看起来像JSON,但具有许多优势,例如注释、更简洁的引号以及编写表达式的能力等。 - Steve Bennett

55

GIT和YAML

其他答案已经很好了,先阅读那些答案。但我会额外补充一个使用YAML的原因:git

越来越多的编程项目使用git仓库进行分发和存档。虽然git仓库的历史可以同样存储JSON和YAML文件,但用于跟踪和显示文件变化的“diff”方法是面向行的。由于YAML被强制为面向行,因此人类更容易看到YAML文件中的任何小变化。

当然,JSON文件也可以通过排序字符串/键并添加缩进来“美化”。但这不是默认设置,而且我懒得这样做。

就个人而言,我通常使用JSON进行系统间交互。我经常使用YAML进行配置文件、静态文件和跟踪文件。 (我一般避免添加YAML关系锚点。生命太短暂了,没必要追寻循环。)

此外,如果速度和空间确实是问题,我都不使用它们。你可以看看BSON。


2
YAML经常被编译成JSON,特别是在使用git时。例如,在GitHub Actions中,需要一个“.workflow.yml”文件来定义工作流程,但当它运行时,它只是被编译成JSON。 - ATYB

28

我觉得YAML更容易阅读:比如括号、引号等字符较少。尽管在YAML中使用制表符可能会有些繁琐,但我们可以逐渐习惯。

就性能和资源而言,我不认为两者之间会有很大的差异。

此外,我们正在讨论配置文件,我不认为会频繁进行编码/解码操作,对吧?


25
我想知道你所说的“标签的烦恼”是什么意思。我相信这个问题是因为在YAML中不允许使用制表符(tab characters),而我个人认为这是任何源文件中的一个好习惯。参考链接:http://www.yaml.org/faq.html,http://www.jwz.org/doc/tabs-vs-spaces.html。 - poolie
8
@poolie: jldupont 可能指的是 YAML 中 语法上具有意义的前导空格 - naught101
13
好的,但它们并不是选项卡。 - poolie

27

从技术上讲,YAMLJSON 提供了更多的功能(YAML v1.2 是 JSON 的超集):

  • 注释
  • 锚点和继承 - 三个相同项的示例:

  • item1: &anchor_name
      name: Test
      title: Test title
    item2: *anchor_name
    item3:
      <<: *anchor_name
      # You may add extra stuff.
    
  • ...

大部分情况下,人们不会使用这些额外的特性,主要的区别在于YAML 使用缩进JSON 使用花括号。这使得 YAML 更加简洁和易读(对于熟练的读者)。

该选择哪一个呢?

  • YAML 的额外特性和简洁表示法使其成为配置文件(非用户提供文件)的良好选择。
  • JSON 的特性有限,支持广泛,解析速度更快,使其成为互操作性和用户提供数据的最佳选择。

23
如果您不需要 YAML 具有而 JSON 没有的任何功能,我会更喜欢使用 JSON,因为它非常简单并且得到广泛支持(在许多语言中都有很多库)。YAML 更复杂,支持较少。我认为解析速度或内存使用量不会有太大差异,也可能不是程序性能的重要部分。

7
YAML 相对于其它格式更复杂的方面是什么? - Accatyyc
20
例如,正如另一个答案中所指出的那样,YAML支持锚点。还有其他特性,比如可扩展的数据类型。这使它更加复杂,需要更大的规范说明。这可能会影响解析器的性能(可以看看这个问题:https://dev59.com/yHE95IYBdhLWcg3wHqIV)。 - Anton Strogonoff
7
如果复杂性能够为你带来实现整体更大的简单性所需的力量,那么复杂性比简单性更好。这在数据模型的复杂性上当然是正确的。 - Coder Guy
4
我可能来晚了,但是YAML可以添加注释而JSON不行。对我来说,这在规范文档方面非常有帮助。 - Moses Liao GZ
2
@Accatyyc。我认为人们在这里询问有关差异的问题,这是YAML并不容易的确切迹象。我从来没有问过JSON的问题(除了“为什么不能在其中添加注释?”)。 - cmroanirgo

19

基准测试结果

以下是一个基准测试的结果,比较了在Python和Perl上加载YAML和JSON所花费的时间。

JSON速度更快,但可读性稍差,并且不支持像注释这样的功能。

测试方法

结果

Python 3.8.3 timeit
    JSON:            0.108
    YAML CLoader:    3.684
    YAML:           29.763

Perl 5.26.2 Benchmark::cmpthese
    JSON XS:         0.107
    YAML XS:         0.574
    YAML Syck:       1.050

Perl 5.26.2 Dumbbench (Brian D Foy, excludes outliers)
    JSON XS:         0.102
    YAML XS:         0.514
    YAML Syck:       1.027

2
JSON更快,因为它不必处理引用、许多类型的容器、标签等。 - funny_falcon

15

来自:Arnaud Lauret《Web API设计》一书:

JSON数据格式

JSON是一种基于JavaScript编程语言描述数据的文本数据格式,尽管它的名称是JavaScript对象表示法(JavaScript Object Notation),但它完全独立于语言(参见https://www.json.org/)。使用JSON,您可以描述包含无序名称/值对的对象以及包含有序值的数组或列表,如下图所示。

enter image description here

一个对象由花括号({})界定。名称是一个带引号的字符串("name"),并且用冒号(:)与其值分隔。值可以是字符串,例如"value",数字,例如1.23,布尔值(true或false),空值null,对象或数组。数组由方括号([])界定,其值由逗号(,)分隔。

JSON格式可以使用任何编程语言轻松解析。它也相对容易阅读和编写。它被广泛用于许多用途,例如数据库、配置文件和API等。

YAML

YAML(YAML Ain’t Markup Language)是一种人性化的数据序列化格式。与JSON类似,YAML(http://yaml.org)是一种键/值数据格式。下图显示了两者的比较。

enter image description here

请注意以下几点:

  • YAML中的属性名称和值周围没有双引号(" ")。

  • JSON中的结构花括号({})和逗号(,)在YAML中被换行符和缩进所代替。

  • 数组方括号([])和逗号(,)在YAML中被破折号(-)和换行符所代替。

  • JSON不同,YAML允许以井号(#)开头的注释。将其中一个格式转换为另一个格式相对容易。但请注意,将YAML文档转换为JSON时会丢失注释。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接