YAML和JSON有什么区别?

What is the difference between YAML and JSON? When to prefer one over the other

考虑到以下几点,我们应该在什么时候使用yaml而不是json,反之亦然?

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

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

相关:

我应该使用yaml或json来存储Perl数据吗?


从技术上讲,yaml是json的超集。这意味着,至少在理论上,yaml解析器可以理解JSON,但不一定是另一种方式。

参见官方规范,标题为"YAML:与JSON的关系"一节。

一般来说,我喜欢一些在JSON中不可用的关于yaml的东西。

  • 正如@jdupont所指出的,yaml在视觉上更容易看到。事实上,yaml主页本身就是有效的yaml,但是对于人来说很容易阅读。
  • yaml能够使用"锚"引用yaml文件中的其他项,因此它可以像在mysql数据库中那样处理关系信息。
  • yaml对于在yaml文件中嵌入其他序列化格式(如json或xml)更为健壮。

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

目前,Ajax和其他Web技术倾向于使用JSON。yaml目前更多地用于离线数据处理。例如,默认情况下,它包含在基于C的Opencv计算机视觉包中,而JSON则不包括在内。

您将找到JSON和YAML的C库。Yaml的图书馆往往比较新,但我过去对它们没什么问题。参见Yaml CPP示例。


差异:

  • yaml的可读性比json高,这取决于您如何使用它。
  • JSON通常更快,而且可能仍然可以与更多的系统进行互操作。
  • 很快就可以编写一个"足够好"的JSON解析器。
  • 重复的键(可能是有效的JSON)绝对是无效的yaml。
  • Yaml有很多特性,包括注释和关系锚。因此,yaml语法相当复杂,很难理解。
  • 可以在yaml:{a: &b [*b]}中编写递归结构,它将在某些转换器中无限循环。即使有了循环检测,"山药炸弹"仍然是可能的(见XML炸弹)。
  • 因为没有引用,所以不可能在JSON中用对象引用序列化复杂的结构。因此,yaml序列化可以更有效。
  • 在某些编码环境中,使用yaml可以让攻击者执行任意代码。
  • 观察:

  • 由于使用缩进而不是括号语法来指示级别,Python程序员通常是Yaml的忠实粉丝。
  • 许多程序员认为"意义"对缩进的附加是一个糟糕的选择。
  • 如果数据格式将离开应用程序的环境、在UI中解析或在消息传递层中发送,那么JSON可能是更好的选择。
  • yaml可以直接用于语法定义之类的复杂任务,通常比发明一种新语言更好。

  • 绕过深奥理论

    这就回答了标题,而不是像我一样从谷歌的搜索结果中读取标题的细节,所以我觉得有必要从Web开发人员的角度进行解释。

  • yaml使用空白缩进,这是Python开发人员熟悉的领域。
  • Javascript开发人员喜欢JSON,因为它是Javascript的一个子集,可以在Javascript中直接解释和编写,并使用一种简单的方法声明JSON,在使用没有空格的典型变量名时,不需要在键中使用双引号。
  • 对于yaml和json,有大量的解析器在所有语言中都能很好地工作。
  • 在许多情况下,Yaml的空白格式更容易查看,因为格式化需要更人性化的方法。
  • 如果编辑器中没有可见的空白或缩进行指示器,那么Yaml的空白虽然更紧凑、更易于查看,但却很难手动编辑。
  • JSON的序列化和反序列化速度要快得多,因为要检查的特性比Yaml少得多,这使得处理JSON的代码更小、更轻。
  • 一个常见的误解是Yaml需要的标点符号更少,而且比JSON更紧凑,但这完全是错误的。空白是不可见的,所以看起来字符较少,但是如果您计算实际的空白,这是必要的,以便正确解释yaml和适当的缩进,您会发现yaml实际上需要比json更多的字符。JSON不使用空白来表示层次结构或分组,并且可以很容易地扁平化,删除不必要的空白以实现更紧凑的传输。
  • 房间里的大象:互联网本身

    显然,javascript在Web上占据了巨大的优势,而javascript开发人员更喜欢将JSON作为数据格式,并与流行的Web API一起使用,因此在一般意义上,在进行Web编程时,使用yaml比json更难争论,因为在团队环境中,您可能会被淘汰。事实上,大多数Web程序员甚至不知道yaml的存在,更不用说考虑使用它了。

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


    这个问题已经6岁了,但奇怪的是,没有一个答案能真正解决这四个问题(速度、记忆、表达能力、可移植性)。

    速度

    显然,这是依赖于实现的,但是由于JSON被广泛使用,并且易于实现,所以它倾向于获得更大的本机支持,从而提高了速度。考虑到Yaml做了JSON所做的一切,再加上一卡车的工作量,在这两者的任何类似实现中,JSON One都将更快。

    但是,考虑到yaml文件可能比它的JSON对应文件稍小(由于",字符较少),在特殊情况下,高度优化的yaml解析器可能更快。

    记忆

    基本上相同的论点也适用。如果它们表示相同的数据结构,那么很难理解为什么yaml解析器比JSON解析器内存效率更高。

    表现力

    正如其他人所指出的,python程序员倾向于选择yaml、javascript程序员而不是json。我将进行以下观察:

    • 很容易记住JSON的整个语法,因此对于理解任何JSON文件的含义非常有信心。山药是任何人都无法真正理解的。微妙和边缘情况的数量是极端的。
    • 因为很少有解析器实现整个规范,所以更难确定给定上下文中给定表达式的含义。
    • 实际上,JSON中缺乏评论是一种真正的痛苦。

    便携性

    很难想象没有JSON库的现代语言。也很难想象一个JSON解析器实现任何低于完整规范的东西。Yaml有广泛的支持,但比JSON不那么普遍,并且每个解析器实现不同的子集。因此,yaml文件的互操作性比您想象的要差。

    总结

    JSON是性能(如果相关)和互操作性的赢家。山药更适合人类保存的文件。HJSON是一个不错的折衷方案,尽管它的可移植性大大降低。JSON5是一个更合理的折衷方案,具有定义良好的语法。


    我发现yaml在眼睛上更容易看到:更少的括号,"等等。尽管yaml中的制表符很烦人…但有人能理解。

    在性能/资源方面,我不希望两者之间有很大的差异。

    此外,我们讨论的是配置文件,所以我不希望有高频率的编码/解码活动,不是吗?


    如果您不需要Yaml拥有的任何特性,而JSON不需要,那么我更喜欢JSON,因为它非常简单,并且得到广泛的支持(有许多语言的库)。山药更复杂,支持度也更低。我不认为解析速度或内存使用会有很大的不同,也许对程序性能的影响不大。


    Git和Yaml

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

    越来越多的编程项目使用Git存储库进行分发和归档。而且,虽然Git repo的历史可以同样存储JSON和YAML文件,但用于跟踪和显示文件更改的"diff"方法是面向行的。由于yaml必须是面向行的,所以yaml文件中的任何小更改都很容易被人看到。

    当然,通过对字符串/键进行排序并添加缩进,可以使JSON文件"漂亮"。但这不是默认值,我很懒惰。

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

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


    从技术上讲,yaml提供了比json更多的功能(yaml v1.2是json的超集):

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

      1
      2
      3
      4
      5
      6
      7
      item1: &anchor_name
        name
      : Test
        title
      : Test title
      item2
      : *anchor_name
      item3
      :
        <<
      : *anchor_name
        # You may add extra stuff.

    大多数时候人们不会使用这些额外的特性,主要的区别是yaml使用缩进,而json使用括号。这使得Yaml更简洁易读(对于受过训练的人来说)。

    选择哪一个?

    • yaml额外的特性和简洁的符号使它成为配置文件(非用户提供的文件)的一个很好的选择。
    • JSON有限的特性、广泛的支持和更快的解析使它成为互操作性和用户提供数据的一个很好的选择。

    有时你不必为一个决定另一个。

    例如,在Go中,您可以同时拥有这两种功能:

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

    由于这个问题在搜索yaml和json时具有突出的特点,所以值得注意的是,很少有人引用这两者之间的区别:许可证。JSON声称拥有JSON用户必须遵守的许可证(包括法律上含糊不清的"应善用,而不是邪恶")。Yaml没有这种许可证申请,这可能是一个重要的区别(对你的律师,如果不是对你)。


    • JSON无法处理大数据。

    • 不适用于处理不同的多媒体格式。

    • JSON没有支持"comments"的功能。这可以单独作为附加属性包括在内。

    • 与JSON相比,YAML具有一些优势,比如自引用、支持复杂数据类型、嵌入块文本、注释等等。

    • JSON只能读取,而YAML既可以读取也可以编辑。
    • JSON是yaml的一个子集,因此yaml解析器可以解析json。
    • Yaml不使用任何额外的分隔符,因此它比XML和JSON更轻。


    我发现Yaml和JSON都非常有效。当一种语言在我身上被使用而另一种语言在我身上被使用时,唯一能真正支配的两件事是一件事,那就是语言最常用的东西。例如,如果我使用Java,JavaScript,我将使用JSON。对于Java,我将使用他们自己的对象,这些对象几乎是JSON,但缺少一些特性,如果需要的话,首先将其转换成JSON,或者在JSON中转换为JSON。我这样做是因为在Java中这是一个常见的事情,让其他Java开发人员更容易修改我的代码。第二件事是我是否使用它来让程序记住属性,或者如果程序正在接收配置文件形式的指令,在这种情况下,我将使用yaml,因为它很容易被人读取,有漂亮的语法,并且很容易修改,即使你不知道yaml是如何工作的。然后,程序将读取它并将其转换为JSON,或者该语言首选的任何语言。最后,老实说,这无关紧要。任何有经验的程序员都很容易阅读JSON和YAML。