YAML和JSON有什么区别?

YAML和JSON有什么区别,特别是考虑到以下几点?

  • 性能(编码/解码时间)
  • 内存消耗
  • 表达清晰度
  • 图书馆可用性,易用性(我更喜欢C)

我计划在我们的嵌入式系统中使用这两个中的一个来存储配置文件。

相关:

我应该使用YAML或JSON来存储我的Perl数据吗?

438883 次浏览

我发现YAML在眼睛上更容易:更少的括号,“”等等,虽然YAML中有制表符的烦恼……但人们得到了它的诀窍。

在性能/资源方面,我预计两者之间不会有太大的差异。

此外,我们正在谈论配置文件,所以我不会期望高频率的编码/解码活动,不是吗?

如果你不需要任何YAML有而JSON没有的特性,我更喜欢JSON,因为它非常简单并且得到广泛支持(有很多语言的库)。YAML更复杂,支持更少。我不认为解析速度或内存使用会有很大的不同,也许不是程序性能的重要组成部分。

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

请参阅官方规格,在标题为"YAML:与JSON的关系"的部分。

一般来说,我喜欢YAML的某些东西在JSON中不可用。

  • 作为@杜邦指出,YAML在视觉上更容易查看。事实上,YAML主页本身就是有效的YAML,但人类很容易阅读。
  • YAML能够使用“锚点”引用YAML文件中的其他项目。因此,它可以像在MySQL数据库中一样处理关系信息。
  • YAML在嵌入其他序列化格式(例如JSON或XML)YAML文件方面更加强大。

在实践中,这最后两点对你或我所做的事情都不重要,但从长远来看,我认为YAML将是一种更健壮和可行的数据序列化格式。

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

您会发现JSON和YAML的C库。YAML的库往往较新,但我过去没有遇到过麻烦。参见示例yaml-cpp

差异:

  1. YAML,取决于你如何使用它,可以比JSON更具可读性
  2. JSON通常是更快,并且可能仍然可以与更多系统互操作
  3. 快速编写“足够好”的JSON解析器是可能的
  4. 重复的键是潜在有效的JSON,是绝对无效的YAML。
  5. YAML有大量的特性,包括注释和关系锚。因此,YAML语法相当复杂,很难理解。
  6. 可以在yaml:{a: &b [*b]}中编写递归结构,这将在某些转换器中无限循环。即使使用循环检测,“yaml炸弹”仍然是可能的(参见xml炸弹)。
  7. 因为没有引用,所以不可能在JSON中使用对象引用序列化复杂结构。因此,YAML序列化可以更有效。
  8. 在某些编码环境中,使用YAML可以允许攻击者执行任意代码

意见:

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

绕过深奥的理论

这回答了标题,而不是细节,因为大多数人只是像我一样从谷歌上的搜索结果中阅读标题,所以我觉得有必要解释从Web开发人员的角度来看

  1. YAML使用空格缩进,这是Python开发人员熟悉的领域。
  2. JavaScript开发人员喜欢JSON,因为它是JavaScript的一个子集,可以直接在JavaScript中解释和编写,同时使用速记方式声明JSON,使用典型的不带空格的变量名时不需要在键中使用双引号。
  3. 有大量的解析器在所有语言中都能很好地用于YAML和JSON。
  4. 在许多情况下,YAML的空格格式更容易查看,因为格式化需要更易于阅读的方法。
  5. 如果您的编辑器中没有可见的空格格式,则YAML的表单虽然更紧凑且更易于查看,但可能难以手动编辑。制表符不是空格,因此如果您没有编辑器将击键解释为空格,则会进一步混淆。
  6. JSON的序列化和反序列化速度要快得多,因为与YAML相比,需要检查的功能要少得多,这使得处理JSON的代码更小、更轻。
  7. 一个常见的误解是YAML需要更少的标点符号并且比JSON更紧凑,但这完全是错误的。空格是不可见的,所以看起来字符更少,但是如果你计算了YAML正确解释所需的实际空格以及适当的缩进,你会发现YAML实际上需要比JSON更多的字符。JSON不使用空格来表示层次结构或分组,并且可以很容易地通过删除不必要的空格来扁平化,以获得更紧凑的传输。

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

JavaScript如此明显地以巨大的优势主导着Web,JavaScript开发人员更喜欢使用JSON作为数据格式,以及流行的Web API,因此在一般意义上进行Web编程时,很难争论使用YAML而不是JSON,因为你可能会在团队环境中被击败。事实上,大多数Web程序员甚至不知道YAML的存在,更不用说考虑使用它了。

如果您正在进行任何Web编程,JSON是默认的方式,因为使用JavaScript时不需要翻译步骤,因此在这种情况下,您必须提出更好的参数来使用YAML而不是JSON。

技术上<强>YAML提供的不仅仅是<强>JSON(YAML v1.2是JSON的超集):

  • 评论数
  • 锚点和继承-3个相同项目的示例:

    item1: &anchor_namename: Testtitle: Test titleitem2: *anchor_nameitem3:<<: *anchor_name# You may add extra stuff.
  • ...

Most of the time people will not use those extra features and the main difference is that YAML uses indentation whilst JSON uses brackets. This makes YAML more concise and readable (for the trained eye).

Which one to choose?

  • YAML extra features and concise notation makes it a good choice for configuration files (non-user provided files).
  • JSON limited features, wide support, and faster parsing makes it a great choice for interoperability and user provided data.

这个问题已经有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是一个更合理的妥协,具有定义良好的语法。

由于这个问题现在在搜索YAML和JSON时非常突出,因此值得注意的是两者之间一个很少被引用的区别:许可证。JSON声称具有JSON用户必须遵守的许可证(包括法律上模棱两可的“应用于善,而不是恶”)。YAML没有这样的许可声明,这可能是一个重要的区别(对你的律师来说,如果不是对你来说)。

我发现YAML和JSON都非常有效。对我来说,真正决定何时使用一种语言而不是另一种语言的唯一两件事是,该语言最常用的是什么。例如,如果我使用Java,Javascript,我会使用JSON。Java,我会使用它们自己的对象,它们几乎是JSON,但缺乏一些功能,如果我需要或将其转换为JSON,或者首先将其转换为JSON。我这样做是因为这在Java很常见,并且使其他Java开发人员更容易修改我的代码。第二件事是,我是否使用它来让程序记住属性,或者如果程序正在接收配置文件形式的指令,在这种情况下,我将使用YAML,因为它很容易被人类阅读,语法漂亮,并且非常容易修改,即使你不知道YAML是如何工作的。然后,程序会读取它并将其转换为JSON,或者该语言首选的任何东西。

最后,老实说这并不重要。任何有经验的程序员都可以轻松阅读JSON和YAML。

有时你不需要选择一个而不是另一个。

例如,在Go中,您可以同时拥有两者:

type Person struct {Name string `json:"name" yaml:"name"`Age int `json:"age" yaml:"age"`}

git和yaml

其他答案都很好。先阅读这些。但我有时会添加另一个使用YAML的原因:git

越来越多的编程项目使用git存储库进行分发和归档。而且,虽然git存储库的历史可以平等地存储JSON和YAML文件,但用于跟踪和显示文件更改的“diff”方法是面向行的。由于YAML被迫面向行,YAML文件中的任何微小更改都更容易被人看到。

当然,JSON文件可以通过对字符串/键进行排序并添加缩进来“变得漂亮”。但这不是默认设置,我很懒。

就个人而言,我通常使用JSON进行系统到系统的交互。我经常使用YAML进行配置文件、静态文件和跟踪文件。(我也通常避免添加YAML关系锚。生命太短,无法追踪循环。)

另外,如果速度和空间真的是一个问题,我也不使用。你可能想看看BSON。

来自:Arnaud Lauret书籍“Web API的设计”。:

JSON数据格式

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

在此处输入图片描述

对象由花括号分隔 ({}). name是一个带引号的字符串("name"),与值之间用冒号(:)分隔。值可以是字符串(如"value")、数字(如1.23)、布尔值(true或false)、空值null、对象或数组。数组由括号分隔 ([]), 其值由逗号(,)分隔。JSON格式很容易使用任何编程语言进行解析。它也相对容易读写。它被广泛用于许多用途,例如数据库、配置文件,当然还有API。

YAML

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

在此处输入图片描述

注意以下几点:

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

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

  • 数组括号([])和逗号(,)被破折号(-)和换行符替换YAML

  • JSON不同,YAML允许以哈希标记(#)开头的注释。将其中一种格式转换为另一种格式相对容易。不过,请注意,在将YAML文档转换为JSON时,您将丢失注释。

基准结果

下面是在Python和Perl上比较YAML与JSON加载时间的基准测试结果

JSON更快,但牺牲了一些易读性和注释等功能

测试方法

搜索结果

Python 3.8.3 timeitJSON:            0.108YAML CLoader:    3.684YAML:           29.763
Perl 5.26.2 Benchmark::cmptheseJSON XS:         0.107YAML XS:         0.574YAML Syck:       1.050
Perl 5.26.2 Dumbbench (Brian D Foy, excludes outliers)JSON XS:         0.102YAML XS:         0.514YAML Syck:       1.027

如果您担心更好的解析速度,那么可以选择将数据存储在JSON中。我必须从文件可能被其他用户修改的位置解析数据,因此我使用YAML,因为它提供了比JSON更好的易读性。您还可以在YAML文件中添加在JSON文件中无法完成的注释。