【问题标题】:Should I use YAML or JSON to store my Perl data? [closed]我应该使用 YAML 还是 JSON 来存储我的 Perl 数据? [关闭]
【发布时间】:2010-12-25 00:09:16
【问题描述】:

在过去 6 个月左右的时间里,我一直在使用 YAML 格式并取得了相当大的成功。

然而,YAML 解析器的纯 Perl 实现相当 烦躁地手写一个可读的文件并且有(在我看来) 烦人的怪癖,例如在文件末尾需要换行符。这也是 与我的程序的其余部分相比,速度非常慢。

我正在考虑我的项目的下一步发展,我正在考虑 改用 JSON(实际上是 YAML 的严格子集) 出去)。但是哪种格式在 Perl 中最受社区关注和努力?

今天看来,这对于简单来说是更好的长期格式 Perl、YAML 或 JSON 中的数据描述,为什么?

【问题讨论】:

  • 你能举一个你说的日期的例子吗?
  • 假设所有的叶子数据都是通用的 perl 标量。我在数组和 perl 哈希中结合了标量。数组和散列可以有元素数组和散列。这是非常普通的数据结构的东西。 :-)
  • 我发现 YAML::Tiny 是可靠的,而且是纯 Perl,只要你愿意接受它的局限性。
  • 您还用这些数据做什么,还有谁必须使用它?真的,没有一般的答案。
  • json 如果您需要传递这些数据。 yaml 仅当您计划通过 hnad 编辑(配置文件)或想要显示(例如配置/结果转储)时

标签: perl json yaml


【解决方案1】:

YAML 与 JSON 在 Perl 中还没有解决,我承认我倾向于在这中间。我的建议是,两者都会让你获得尽可能多的社区牵引力。我会根据格式的各种利弊做出决定。我分解了各种数据序列化选项,如下所示(我将访问社区 wiki,以便人们可以添加):

YAML 专家

  • 人性化,人们在不知不觉中编写基本 YAML
  • WYSIWYG strings
  • 富有表现力(具有 TMTOWDI 特性)
  • Expandable type/metadata system
  • Perl 兼容的数据类型
  • 便携
  • 熟悉(很多内联和字符串语法看起来像 Perl 代码)
  • 如果您有编译器 (YAML::XS),则可以很好地实现
  • 良好的 Perl 数据转储能力
  • 紧凑使用屏幕空间(可能,您可以格式化以适应一行)

YAML 缺点

  • Large spec
  • 不可靠/不完整的纯 Perl 实现
  • 空格作为语法可能会引起争议。

JSON 专家

  • 人类可读/可写
  • 小规格
  • 良好的实现
  • 便携
  • Perlish 语法
  • YAML 1.2 is a superset of JSON
  • 紧凑使用屏幕空间
  • Perl 友好的数据类型
  • 很多东西都处理 JSON

JSON 缺点

  • 字符串不是所见即所得
  • 没有可扩展性
  • 某些 Perl 结构必须以特定方式表示(对象和全局对象)
  • 缺乏表达性

XML 专家

  • 广泛使用
  • Web 开发人员熟悉的语法
  • 优质 XML 模块的大型语料库
  • 架构
  • 搜索和转换数据的技术
  • 便携

XML 缺点

  • 人类阅读和写作很乏味
  • Perl 以外的数据结构
  • 缺乏表达性
  • 大规格
  • 详细

Perl/Data::Dumper Pros

  • 无依赖关系
  • 出奇的紧凑(带有正确的标志)
  • Perl 友好
  • 几乎可以转储任何东西(通过DDS
  • 富有表现力
  • 紧凑使用屏幕空间
  • WYSIWYG strings
  • 熟悉

Perl/Data::Dumper 缺点

  • 不可移植(到其他语言)
  • 不安全(没有英勇的措施)
  • 非 Perl 程序员难以理解

可存储的优点

  • 紧凑? (没有数字支持)
  • 快吗? (没有数字支持)

可存储的缺点

  • 人类敌对
  • Storable 版本不兼容
  • 不可移植(到其他语言)

【讨论】:

  • 在 Stack Overflow 上有一篇文章说 JSON 对于一个非常简单但比 Storable 大的数据结构更快。
  • 如果你使用 nfreeze() 而不是 freeze(),Storable 的输出将是可移植的
  • @nick 我的意思是不能跨语言移植。
  • JSON 与 YAML 的基准测试结果在此处的答案之一中:stackoverflow.com/questions/1726802/…
  • 请注意,Data::Dumper 和 Storable 都存在安全问题,因为它们可能会尝试膨胀 Perl 对象。那运行代码,它可能不是你期望的代码。
【解决方案2】:

与大多数事情一样,这取决于。我认为如果您想要速度和互操作性(与其他语言),请使用 JSON,尤其是 JSON::XS

如果您想要一些只能被 Perl 模块使用的东西,请坚持使用 YAML。在 CPAN 上找到支持使用 YAML 进行数据描述或依赖于 YAML 的 Perl 模块比 JSON 更常见。

请注意,我不是权威,这种观点主要基于预感和猜想。特别是,我没有分析 JSON::XS 与 YAML::XS。如果我无知得冒犯,我只能希望我能通过纠正我让某人愤怒到为讨论带来有用的信息。

【讨论】:

    【解决方案3】:

    一切都与人类可读性有关,如果这是您的主要关注点,请选择 YAML:

    YAML:

    american:
      - Boston Red Sox
      - Detroit Tigers
      - New York Yankees
    national:
      - New York Mets
      - Chicago Cubs
      - Atlanta Braves
    

    JSON:

    {
      "american": [
        "Boston Red Sox", 
        "Detroit Tigers", 
        "New York Yankees"
      ], 
      "national": [
        "New York Mets", 
        "Chicago Cubs", 
        "Atlanta Braves"
      ]
    }
    

    【讨论】:

    • 不同的人会有不同的答案,哪个更易读:)
    • 虽然可读性有点主观,但其中一个看起来像是我可能会在电子邮件中写的东西,而另一个却不是。
    • 在 YAML 中你可以放置 cmets。这在 JSON 中是不可能的。这是人类可写性的一个主要问题。
    • @dolmen 是的,但这通常不是从“Json”切换到“Yaml”的好理由
    • @PHPst 问题不在于切换数据格式,而在于为任务选择更合适的格式。
    【解决方案4】:

    纯 Perl YAML 实现(YAML 模块而不是 YAML::Syck)似乎有一些严重的问题。我最近遇到了无法处理行很长(大约 32k 个字符)的 YAML 文档的问题。

    YAML 能够存储和加载祝福变量,并通过 默认(下面的 sn-p 是从 *sepia-repl* 缓冲区复制的 Emacs):

    I need user feedback!  Please send questions or comments to seano@cpan.org.
    Sepia version 0.98.
    Type ",h" for help, or ",q" to quit.
    main @> use YAML
    undef
    main @> $foo = bless {}, 'asdf'
    bless( {}, 'asdf' )
    main @> $foo_dump = YAML::Dump $foo
    '--- !!perl/hash:asdf {}
    '
    main @> YAML::Load $foo_dump
    bless( {}, 'asdf' )
    

    这在安全方面非常可怕,因为可以使用不受信任的数据 调用已在您的应用程序中定义的任何 DESTROY 方法 -- 或它使用的任何模块。

    下面的小程序演示了这个问题:

    #!/usr/bin/perl
    use YAML;
    use Data::Dumper;
    package My::Namespace;
    sub DESTROY {
        print Data::Dumper::Dumper \@_;
    }
    package main;
    my $var = YAML::Load '--- !!perl/hash:My::Namespace
    bar: 2
    foo: 1
    ';
    

    默认情况下 JSON 不允许这样做——可以序列化 Perl“对象”,但为了做到这一点,你必须定义 TO_JSON 方法。

    【讨论】:

    • +1 以获得良好的信息和安全说明。
    • 目前有一些工作将 Pure Perl YAML 模块移动到 YAML::PP。然后拥有一个新的 YAML 模块,它会自动为您选择其中一种实现。 (这是 JSON 模块当前所做的)。
    • 布拉德吉尔伯特:这似乎是件好事。是否有任何计划为了安全而破坏兼容性——至少对于Load 函数?
    【解决方案5】:

    我使用 YAML 来跟踪进程的状态,因为我可以在进程中间读取 YML。您(技术上)需要完整格式的文档来读取 XML 或 JS。 YAML 非常适合跟踪状态,因为您可以将大量迷你文档写入文件。否则,我通常使用 XML 或 JS。顺便说一句,很好地总结了上面的利弊。

    【讨论】:

      【解决方案6】:

      如果您正在考虑 JavaScript 对象表示法,为什么不使用“Perl 对象表示法”?

      JSON:

      {"name": "bob", "parents": {"mother": "susan", "father": "bill"}, "nums": [1, 2, 3]}
      

      Perl:

      {name => "bob", parents => {mother => "susan", father => "bill"}, nums => [1, 2, 3]}
      

      【讨论】:

      • (1)解析器是字符串eval; (2)Data::Dumper 加载/存储需要在加载和存储例程之间进行一些粗糙的耦合。此外,最重要的是,“PON”不是标准的交换格式。 JSON 是,YML 也是(在 Perl 中)。
      【解决方案7】:

      您可能还想考虑使用Storable。你可能会得到一个非常好的速度提升。权衡是:

      • Storable 格式是二进制的,不像 JSON 或 YAML 那样人类可读
      • Storable 不是纯粹的 Perl 模块(如果重要的话)

      【讨论】:

      • 在这样的速度方面,我怀疑“不是纯 Perl”更好
      • 在这个特定的上下文中,由于我无法控制的情况,需要纯 perl。但是,我同意不纯纯几乎肯定会更好地提高速度。
      • @Paul Nathan:如果问题是编译涉及 C 扩展的模块,Storable 是内置的。所以没有必要以后再买。如果你有 Perl,你已经有 Storable。
      • 好吧。无知被暴露和减少。 :-)
      • 一位朋友最近做了一些基准测试,比较了 Storable、JSON::XS 和 YAML::Syck 的速度,而 JSON::XS 的速度要快得多。
      猜你喜欢
      • 1970-01-01
      • 2011-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      相关资源
      最近更新 更多