我应该使用 YAML 还是 JSON 来存储我的 Perl 数据? [关闭]

Posted

技术标签:

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

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

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

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

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

【问题讨论】:

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

以上是关于我应该使用 YAML 还是 JSON 来存储我的 Perl 数据? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

我应该在 MySQL 中为 JSON 使用 blob 还是 text?

Git 日志输出到 XML、JSON 还是 YAML?

我应该在 Doctrine 2 中使用 YAML/XML 还是注解映射?

app.yaml 与 appengine-web.xml 使用哪一个?

cloudbuild.yaml 中构建步骤中的 gcloud beta 命令。我应该使用入口点还是参数?

创建一个 api 以使用 json 或 yaml 有效负载更新 postgres db