在Python中,json序列化是如何比yaml序列化更快的呢?

我有严重依赖yaml进行跨语言序列化的代码,并在加速某些东西的同时,我发现yaml与其他序列化方法(例如pickle,json)相比,速度非常慢。

所以真正打动我的是,当输出几乎相同时,json的速度要快得多。

>>> import yaml, cjson; d={'foo': {'bar': 1}} >>> yaml.dump(d, Dumper=yaml.SafeDumper) 'foo: {bar: 1}\n' >>> cjson.encode(d) '{"foo": {"bar": 1}}' >>> import yaml, cjson; >>> timeit("yaml.dump(d, Dumper=yaml.SafeDumper)", setup="import yaml; d={'foo': {'bar': 1}}", number=10000) 44.506911039352417 >>> timeit("yaml.dump(d, Dumper=yaml.CSafeDumper)", setup="import yaml; d={'foo': {'bar': 1}}", number=10000) 16.852826118469238 >>> timeit("cjson.encode(d)", setup="import cjson; d={'foo': {'bar': 1}}", number=10000) 0.073784112930297852 

PyYaml的CSafeDumper和cjson都是用C语言编写的,所以它不是像C vs Python的速度问题。 我甚至给它添加了一些随机数据来查看cjson是否正在进行caching,但是它比PyYaml还要快。 我意识到yaml是json的一个超集,但是yaml序列化器如何在这样简单的input下慢两个数量级呢?

一般来说,决定parsing速度的并不是输出的复杂度,而是接受input的复杂度。 JSON语法非常简洁 。 YAMLparsing器比较复杂 ,导致开销增加。

JSON最重要的devise目标是简单和普遍。 因此,JSON是微不足道的生成和parsing,代价是降低了人的可读性。 它还使用最低公分母信息模型,确保每个现代编程环境都可以轻松处理任何JSON数据。

相比之下,YAML的最重要的devise目标是人类的可读性,并支持序列化任意本地数据结构。 因此,YAML允许非常易读的文件,但是生成和parsing更复杂。 另外,YAML冒险超越最低公分母数据types,在不同的编程环境之间交叉时需要更复杂的处理。

我不是一个YAMLparsing器的实现者,所以我不能没有一些分析数据和一个大的语料库来具体说明数量级的问题。 在任何情况下,都要确保在对基准数字有信心之前对大量input进行testing。

更新 Whoops,误解了这个问题。 :-(尽pipe有很大的input语法,但序列化的速度仍然非常快;但是,浏览源代码,PyYAML的Python级序列化构build了一个表示图,而Simplejson直接将内置的Python数据types编码为文本块。

在我工作的应用程序中,string到数字(float / int)之间的types推断是parsingyaml的最大开销之处,因为string可以不带引号来编写。 因为json中的所有string都在引号中,所以在parsingstring时没有回溯。 一个很好的例子,这将减慢是值0000000000000000000s。 直到读完为止,您才能知道这个值是一个string。

其他答案是正确的,但这是我在实践中发现的一个具体细节。

谈到效率,我用了YAML一段时间,并且被一些名字/价值任务在这个语言中的简单性所吸引。 然而,在这个过程中,我经常绊倒YAML的一个企业,语法的微妙变化使您能够以更简洁的风格编写特殊的案例。 最后,虽然YAML的语法在forms上几乎是一致的,但却给我留下了一种“模糊”的感觉。 然后,我限制自己不要触摸现有的,正在运行的YAML代码,并用一个更迂回的,故障安全的语法来写新的东西 – 这使我放弃了所有的YAML。 结果是,YAML试图看起来像一个W3C标准,并产生了一个关于其概念和规则的难以阅读文献的小型图书馆。

我觉得这是比所需要的更多的智力开销。 看一下SGML / XML:由IBM在60年代发展起来的,由ISO标准化的,被称为HTML(以一种虚拟和修改的forms)作为HTML,为数不清的人进行logging和logging,并再次logging在全世界。 出现小JSON并杀死龙。 JSON如此短时间内如此广泛地被使用,只有一个微不足道的网站(还有一个JavaScript的支持者)呢? 它的简单性,语法上毫无疑问,易于学习和使用。

XML和YAML对于人类来说很难,而且对于计算机来说是很难的。 JSON对人类和计算机都相当友好和容易。

粗略的看python-yaml表明它的devise比cjson更复杂:

 >>> dir(cjson) ['DecodeError', 'EncodeError', 'Error', '__doc__', '__file__', '__name__', '__package__', '__version__', 'decode', 'encode'] >>> dir(yaml) ['AliasEvent', 'AliasToken', 'AnchorToken', 'BaseDumper', 'BaseLoader', 'BlockEndToken', 'BlockEntryToken', 'BlockMappingStartToken', 'BlockSequenceStartToken', 'CBaseDumper', 'CBaseLoader', 'CDumper', 'CLoader', 'CSafeDumper', 'CSafeLoader', 'CollectionEndEvent', 'CollectionNode', 'CollectionStartEvent', 'DirectiveToken', 'DocumentEndEvent', 'DocumentEndToken', 'DocumentStartEvent', 'DocumentStartToken', 'Dumper', 'Event', 'FlowEntryToken', 'FlowMappingEndToken', 'FlowMappingStartToken', 'FlowSequenceEndToken', 'FlowSequenceStartToken', 'KeyToken', 'Loader', 'MappingEndEvent', 'MappingNode', 'MappingStartEvent', 'Mark', 'MarkedYAMLError', 'Node', 'NodeEvent', 'SafeDumper', 'SafeLoader', 'ScalarEvent', 'ScalarNode', 'ScalarToken', 'SequenceEndEvent', 'SequenceNode', 'SequenceStartEvent', 'StreamEndEvent', 'StreamEndToken', 'StreamStartEvent', 'StreamStartToken', 'TagToken', 'Token', 'ValueToken', 'YAMLError', 'YAMLObject', 'YAMLObjectMetaclass', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__version__', '__with_libyaml__', 'add_constructor', 'add_implicit_resolver', 'add_multi_constructor', 'add_multi_representer', 'add_path_resolver', 'add_representer', 'compose', 'compose_all', 'composer', 'constructor', 'cyaml', 'dump', 'dump_all', 'dumper', 'emit', 'emitter', 'error', 'events', 'load', 'load_all', 'loader', 'nodes', 'parse', 'parser', 'reader', 'representer', 'resolver', 'safe_dump', 'safe_dump_all', 'safe_load', 'safe_load_all', 'scan', 'scanner', 'serialize', 'serialize_all', 'serializer', 'tokens'] 

更复杂的devise几乎总是意味着更慢的devise,这比大多数人所需要的要复杂得多。