哪个更快 - 加载一个被pickle的字典对象还是加载JSON文件到字典?

15

什么更快:

(A) 使用pickle.load()反序列化(pickled)字典对象, 或

(B) 使用simplejson.load()从JSON文件加载到字典中

假设: 在情况A中,pickled对象文件已经存在;在情况B中,JSON文件已经存在。


10
为什么要在互联网上询问陌生人?量力而行! - NPE
3
实际上,这将取决于内容类型、长度和整体大小...另外,在进行此操作时,您可能还想尝试使用cPickle和cjson(后者适用于2.x.x,cjson不适用于3.x.x)进行时间测试。 - Nisan.H
2
除了@Nisan.H所说的之外,还有第三方(即在PyPI上)JSON库声称速度显著更快。 - user395760
1个回答

28

实际上,速度取决于数据的内容和大小。

但是,不管怎样,我们可以举个例子,看看哪种方法更快(Ubuntu 12.04,Python 2.7.3):

假设有这个JSON结构被转储到test.jsontest.pickle文件中:

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

测试脚本:

import timeit

import pickle
import cPickle

import json
import simplejson
import ujson
import yajl


def load_pickle(f):
    return pickle.load(f)


def load_cpickle(f):
    return cPickle.load(f)


def load_json(f):
    return json.load(f)


def load_simplejson(f):
    return simplejson.load(f)


def load_ujson(f):
    return ujson.load(f)


def load_yajl(f):
    return yajl.load(f)


print "pickle:"
print timeit.Timer('load_pickle(open("test.pickle"))', 'from __main__ import load_pickle').timeit()

print "cpickle:"
print timeit.Timer('load_cpickle(open("test.pickle"))', 'from __main__ import load_cpickle').timeit()

print "json:"
print timeit.Timer('load_json(open("test.json"))', 'from __main__ import load_json').timeit()

print "simplejson:"
print timeit.Timer('load_simplejson(open("test.json"))', 'from __main__ import load_simplejson').timeit()

print "ujson:"
print timeit.Timer('load_ujson(open("test.json"))', 'from __main__ import load_ujson').timeit()

print "yajl:"
print timeit.Timer('load_yajl(open("test.json"))', 'from __main__ import load_yajl').timeit()

输出:

pickle:
107.936687946

cpickle:
28.4231381416

json:
31.6450419426

simplejson:
20.5853149891

ujson:
16.9352178574

yajl:
18.9763481617

从结果可以看出,使用pickle进行反序列化的速度并不快 - 如果选择序列化/反序列化选项,那么cPickle绝对是首选。在这些JSON解析器中,ujson在特定数据上看起来很有前途。

此外,jsonsimplejson库在pypy上加载速度要快得多(请参见Python JSON性能)。

另请参见:

需要注意的是,在您的特定系统以及其他类型和大小的数据上,结果可能会有所不同。


1
当您使用cpickle进行示例时,您得到了什么时间? - Kevin London
稍等一下,我会添加 ujsoncPickle - alecxe
3
请见更新的答案。cPickleujson 在这里改变了整个情况 :) - alecxe
1
yajl添加到基准测试中。 - alecxe
4
反复打开同一个文件通常会导致文件被磁盘缓存。如果更改测试的顺序,你的结果会发生变化吗? - Steven Rumbalski
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接