我可以加速YAML吗?

我制作了一个小测试用例来比较YAML和JSON的速度:

导入json
进口yaml
从日期时间导入日期时间
从随机导入randint
NB_行=1024
打印“yaml是否正在使用libyaml?”,yaml.u_u与_ulibyaml_u_u以及“是”或“否”
dummy_data=[{‘dummy_key_A_%s’%i:i’,dummy_key_B_%s’%i:i}用于xrange中的i(NB_行)]
以open(’perf_json_yaml.yaml’,’w’)作为fh:
t1=datetime.now()
yaml.safe_dump(伪数据,fh,编码=’utf-8’,默认流量样式=False)
t2=datetime.now()
dty=(t2-t1).总秒数()
打印“正在将%s行转储到yaml文件中:%s%”(NB_行,dty)
以open(’perf_json_yaml.json’,’w’)作为fh:
t1=datetime.now()
json.dump(伪_数据,fh)
t2=datetime.now()
dtj=(t2-t1).total_seconds()
打印“正在将%s行转储到json文件中:%s%”(NB_行,dtj)
打印“json转储速度快%dx”%(dty/dtj)
以open(“perf_json_yaml.yaml”)作为fh:
t1=datetime.now()
数据=yaml.安全荷载(fh)
t2=datetime.now()
dty=(t2-t1).总秒数()
打印“正在从yaml文件加载%s行:%s%”(NB_行,dty)
以open(’perf_json_yaml.json’)作为fh:
t1=datetime.now()
data=json.load(fh)
t2=datetime.now()
dtj=(t2-t1).total_seconds()
打印“正在将%s行从json文件加载到:%s%”(NB_行,dtj)
打印“json加载速度快%dx%”(dty/dtj)

结果是:

yaml是否正在使用libyaml?对
正在将1024行转储到yaml文件:0.251139
正在将1024行转储到json文件:0.007725
json转储速度快32倍
正在从yaml文件加载1024行:0.401224
正在将1024行从json文件加载到:0.001793
json的加载速度快了223倍

我在Ubuntu12.04上使用Pyyaml3.11和libyamlC库。
我知道json比yaml简单得多,但json和yaml的比例是223倍,我想知道我的配置是否正确

你们有相同的速比吗?
我如何加速yaml.load()

您可能已经注意到Python的数据结构语法与JSON的语法非常类似

所发生的事情是Python的json库将Python的内置数据类型直接编码为文本块,将替换为,并在此处或此处删除(稍微简化)

另一方面,pyyaml必须先构造一个完整的表示图,然后才能将其序列化为字符串

加载时,同样的情况必须向后发生

加速yaml.load()的唯一方法是编写一个新的Loader,但我怀疑这可能是性能上的巨大飞跃,除非您愿意编写自己的单一用途的yaml解析器,并考虑以下注释:

YAML构建图形是因为它是一种通用序列化
能够表示对同一对象的多个引用的格式
对象。如果您知道没有对象重复,并且只显示基本类型,
您可以使用json序列化器,它仍然是有效的YAML

更新

我之前所说的仍然正确,但是如果您正在运行Linux,有一种方法可以加速Yaml解析。默认情况下,Python的Yaml使用Python解析器。您必须告诉它您想要使用PyYamlC解析器

您可以这样做:

导入yaml
从yaml进口装载机作为装载机,从CDumper作为卸载机
dump=yaml.dump(伪数据,fh,编码=’utf-8’,默认流样式=False,转储程序=Dumper)
数据=yaml.荷载(fh,装载机=装载机)

为此,您需要安装yaml-cpp-dev(软件包后来重命名为libyaml-cpp-dev),例如,安装apt-get:

$apt get安装yaml cpp dev

还有PyYamlLibYaml。但根据您的输出,情况已经是这样了

我现在无法测试它,因为我正在运行OS X,并且brew在安装yaml cpp dev时遇到一些问题,但是如果您遵循PyYaml文档,他们很清楚性能会更好

发表评论