泡椒还是json?

时间:2010-02-13 22:12:56

标签: python json pickle

我需要将一个dict对象保存到磁盘,该对象的密钥类型为str,值为int s ,然后将其恢复。像这样:

{'juanjo': 2, 'pedro':99, 'other': 333}

最佳选择是什么?为什么?使用picklesimplejson

对其进行序列化

我正在使用Python 2.6。

7 个答案:

答案 0 :(得分:91)

我喜欢JSON而不是pickle来进行序列化。 Unpickling可以运行任意代码,使用pickle在程序之间传输数据或在会话之间存储数据是一个安全漏洞。 JSON没有引入安全漏洞并且是标准化的,因此如果您需要,可以使用不同语言的程序访问数据。

答案 1 :(得分:62)

如果您没有任何互操作性要求(例如,您只是将数据与Python一起使用)并且二进制格式正常,请使用cPickle,这样可以实现快速的Python对象序列化。

如果您需要互操作性,或者希望文本格式存储数据,请使用JSON(或其他一些适当的格式,具体取决于您的约束)。

答案 2 :(得分:42)

您可能也会觉得这很有趣,有些图表需要比较:http://kovshenin.com/archives/pickle-vs-json-which-is-faster/

答案 3 :(得分:19)

如果您主要关心速度和空间,请使用cPickle,因为cPickle比JSON更快。

如果您更关注互操作性,安全性和/或人类可读性,请使用JSON。

其他答案中引用的测试结果记录在2010年,2016年cPickle protocol 2的更新测试显示:

  • cPickle加载速度提高3.8倍
  • cPickle读取速度提高1.5倍
  • cPickle略小的编码

使用this gist自行重现,这是基于其他答案中引用的Konstantin's benchmark,但使用cPickle与协议2而不是pickle,并使用json而不是simplejson(因为 json比simplejson 更快,例如

wget https://gist.github.com/jdimatteo/af317ef24ccf1b3fa91f4399902bb534/raw/03e8dbab11b5605bc572bc117c8ac34cfa959a70/pickle_vs_json.py
python pickle_vs_json.py

在一个体面的2015 Xeon处理器上使用python 2.7的结果:

Dir Entries Method  Time    Length

dump    10  JSON    0.017   1484510
load    10  JSON    0.375   -
dump    10  Pickle  0.011   1428790
load    10  Pickle  0.098   -
dump    20  JSON    0.036   2969020
load    20  JSON    1.498   -
dump    20  Pickle  0.022   2857580
load    20  Pickle  0.394   -
dump    50  JSON    0.079   7422550
load    50  JSON    9.485   -
dump    50  Pickle  0.055   7143950
load    50  Pickle  2.518   -
dump    100 JSON    0.165   14845100
load    100 JSON    37.730  -
dump    100 Pickle  0.107   14287900
load    100 Pickle  9.907   -

Python 3.4 with pickle protocol 3 is even faster.

答案 4 :(得分:11)

JSON还是泡菜? JSON 泡菜怎么样!您可以使用jsonpickle。它易于使用,磁盘上的文件是可读的,因为它是JSON。

http://jsonpickle.github.com/

答案 5 :(得分:4)

就个人而言,我通常更喜欢JSON,因为数据人类可读。当然,如果你需要序列化JSON不会采取的东西,而不是使用pickle。

但对于大多数数据存储,您不需要序列化任何奇怪的东西,JSON更容易,并且总是允许您在文本编辑器中将其弹出并自行检查数据。

速度很快,但对于大多数数据集而言,差异可以忽略不计;不管怎样,Python通常都不会太快。

答案 6 :(得分:4)

我尝试了几种方法,发现使用cPickle将dumps方法的protocol参数设置为:import msgpack import json import pickle import timeit import cPickle import numpy as np num_tests = 10 obj = np.random.normal(0.5, 1, [240, 320, 3]) command = 'pickle.dumps(obj)' setup = 'from __main__ import pickle, obj' result = timeit.timeit(command, setup=setup, number=num_tests) print("pickle: %f seconds" % result) command = 'cPickle.dumps(obj)' setup = 'from __main__ import cPickle, obj' result = timeit.timeit(command, setup=setup, number=num_tests) print("cPickle: %f seconds" % result) command = 'cPickle.dumps(obj, protocol=cPickle.HIGHEST_PROTOCOL)' setup = 'from __main__ import cPickle, obj' result = timeit.timeit(command, setup=setup, number=num_tests) print("cPickle highest: %f seconds" % result) command = 'json.dumps(obj.tolist())' setup = 'from __main__ import json, obj' result = timeit.timeit(command, setup=setup, number=num_tests) print("json: %f seconds" % result) command = 'msgpack.packb(obj.tolist())' setup = 'from __main__ import msgpack, obj' result = timeit.timeit(command, setup=setup, number=num_tests) print("msgpack: %f seconds" % result) 是最快的转储方法。

pickle         :   0.847938 seconds
cPickle        :   0.810384 seconds
cPickle highest:   0.004283 seconds
json           :   1.769215 seconds
msgpack        :   0.270886 seconds

输出:

user.id