为什么用`pickle`倾销比`json`快得多?

时间:2017-03-27 21:25:19

标签: python json benchmarking pickle

这适用于Python 3.6。

编辑并删除了许多与之无关的内容。

我原以为jsonpickle更快,而Stack Overflow上的其他答案和评论也让很多其他人也相信这一点。

我的考试是犹太洁净吗?差距远大于我的预期。我在非常大的对象上得到了相同的结果测试。

import json
import pickle
import timeit

file_name = 'foo'
num_tests = 100000

obj = {1: 1}

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 = 'json.dumps(obj)'
setup = 'from __main__ import json, obj'
result = timeit.timeit(command, setup=setup, number=num_tests)
print("json:   %f seconds" % result)

和输出:

pickle: 0.054130 seconds
json:   0.467168 seconds

3 个答案:

答案 0 :(得分:2)

我已经尝试了几种基于你的代码片段的方法,并发现使用cPickle将dumps方法的protocol参数设置为:cPickle.dumps(obj, protocol=cPickle.HIGHEST_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

答案 1 :(得分:0)

JSON以人类可读的方式序列化。 pickle以二进制表示形式序列化。然而,泡菜通常很慢。像cPickle这样的变体更快。如果您想要更好的序列化,请使用msgpack。

答案 2 :(得分:-1)

您运行基准测试的次数是多少?在任何情况下,您都需要删除线程阻塞等引入的随机延迟。您可以通过足够多次运行基准来实现。此外,您的输入太小,无法抑制“锅炉”代码的任何延迟。