【发布时间】:2012-12-01 01:42:16
【问题描述】:
我用 pickle 测试了三种不同的协议; 0、1、2。
在我的测试中,我倾倒并加载了大约 270000 个(int、int)对中的一个 dict 和一个带有大约 560000 个 int 的 set。
以下是我的测试代码(您可以放心地跳过我用来从数据库中获取数据的两个 fetch 函数):
protocol = 0 # Tested 0, 1, and 2
print 'Protocol:', protocol
t0 = time.time()
sku2spu_dict = fetch_sku2spu_dict()
pid_set = fetch_valid_pids()
t1 = time.time()
print 'Time in sql:', t1 - t0
pickle.dump(sku2spu_dict, open('sku.pcike_dict', 'w'), protocol)
pickle.dump(pid_set, open('pid.picke_set', 'w'), protocol)
t2 = time.time()
print 'Time in dump:', t2 - t1
sku2spu_dict = pickle.load(open('sku.pcike_dict', 'r'))
pid_set = pickle.load(open('pid.picke_set', 'r'))
t3 = time.time()
print 'Time in load:', t3 - t2
以下是每个人花费的时间:
Protocol: 0
Time in dump: 31.3491470814
Time in load: 29.8991980553
Protocol: 1
Time in dump: 32.3191611767
Time in load: 20.6666529179
Protocol: 2
Time in dump: 94.2163629532
Time in load: 42.7647490501
令我惊讶的是,协议 2 比 0 和 1 差得多。
但是,转储文件的大小在协议 2 中是最小的,大约是协议 0 和 1 的一半。
在文档中,它说:
协议版本 2 是在 Python 2.3 中引入的。它提供了更有效的新式类的酸洗。
对于new-style classes的定义,它说:
从对象继承的任何类。这包括所有内置类型,如 list 和 dict
所以我希望协议 2 在转储和加载对象方面更快。
有人知道为什么吗?
更新:
将pickle 替换为cPickle 后问题解决。
现在load 和dump 使用协议 2 需要 5 和 3 秒,而协议 0 和 1 需要超过 10 秒。
【问题讨论】:
-
出于兴趣,您的计时方法是什么?凡涉及执行速度的问题,通常最好给出自己运行测试所需的一切。
-
@Lattyware 请查看更新后的帖子。
-
那种测试不是很准确,不如看看the
timeitmodule。 -
更多的是
timeit多次运行测试以检查它不是异常。它还可以更轻松地与替代品进行比较。 -
听起来“更高效”是指磁盘上的空间,而不是在这种情况下的执行时间。