是否有一个带有python绑定的最新快速YAML解析器?

时间:2013-05-31 19:03:45

标签: python performance yaml

Python中快速YAML解析的最新和最好的是什么? Syck是out of date并建议使用PyYaml,但PyYaml非常慢,并且受到GIL问题的困扰:

>>> def xit(f, x):
        import threading
        for i in xrange(x):
                threading.Thread(target=f).start()

>>> def stressit():
        start = time.time()
        res = yaml.load(open(path_to_11000_byte_yaml_file))
        print "Took %.2fs" % (time.time() - start,)    

>>> xit(stressit, 1)
Took 0.37s
>>> xit(stressit, 2)
Took 1.40s
Took 1.41s
>>> xit(stressit, 4)
Took 2.98s
Took 2.98s
Took 2.99s
Took 3.00s

根据我的用例,我可以缓存已解析的对象,但我仍然更喜欢更快的解决方案。

1 个答案:

答案 0 :(得分:6)

链接的Wiki页面在警告“使用libyaml(c)和PyYaml(python)”之后说明。虽然该笔记确实有一个糟糕的wikilink(应该是PyYAML而不是PyYaml)。

至于性能,根据你安装PyYAML的方式,你应该有CParser类可用,它实现了用优化的C编写的YAML解析器。虽然我认为这不会解决GIL问题,但它明显更快。以下是我在机器上运行的一些粗略基准测试(AMD Athlon II X4 640,3.0GHz,8GB RAM):

首先使用默认的纯Python解析器:

$ /usr/bin/python2 -m timeit -s 'import yaml; y=file("large.yaml", "r").read()' \
    'yaml.load(y)'                    
10 loops, best of 3: 405 msec per loop

使用CParser:

$ /usr/bin/python2 -m timeit -s 'import yaml; y=file("large.yaml", "r").read()' \
    'yaml.load(y, Loader=yaml.CLoader)'
10 loops, best of 3: 59.2 msec per loop

而且,为了比较,使用纯Python解析器使用PyPy。

$ pypy -m timeit -s 'import yaml; y=file("large.yaml", "r").read()' \
    'yaml.load(y)'
10 loops, best of 3: 101 msec per loop

对于large.yaml我只是用谷歌搜索“大型yaml文件”并遇到了这个问题:

https://gist.github.com/nrh/667383/raw/1b3ba75c939f2886f63291528df89418621548fd/large.yaml

(我必须删除前几行以使其成为单文档YAML文件,否则yaml.load会抱怨。)

编辑:

要考虑的另一件事是使用multiprocessing模块而不是线程。这解决了GIL问题,但需要更多的样板代码才能在进程之间进行通信。虽然有许多好的库可以使多处理更容易。有一个非常好的列表here