Python 为什么Pickle协议4中的Pickle文件比协议3中的文件大两倍,而速度却没有任何提高?
我正在测试Python3.4,我注意到pickle模块有一个新的协议。因此,我对2个协议进行了基准测试Python 为什么Pickle协议4中的Pickle文件比协议3中的文件大两倍,而速度却没有任何提高?,python,python-3.x,Python,Python 3.x,我正在测试Python3.4,我注意到pickle模块有一个新的协议。因此,我对2个协议进行了基准测试 def test1(): pickle3=open("pickle3","wb") for i in range(1000000): pickle.dump(i,pickle3,3) pickle3.close() pickle3=open("pickle3","rb") for i in range(1000000):
def test1():
pickle3=open("pickle3","wb")
for i in range(1000000):
pickle.dump(i,pickle3,3)
pickle3.close()
pickle3=open("pickle3","rb")
for i in range(1000000):
pickle.load(pickle3)
def test2():
pickle4=open("pickle4","wb")
for i in range(1000000):
pickle.dump(i, pickle4,4)
pickle3.close()
pickle4=open("pickle4","rb")
for i in range(1000000):
pickle.load(pickle4)
test1标记:在6.473秒内调用2000007个函数
test2标记:在6.740秒内调用2000007个函数
协议4略慢于协议3。这种差异可以忽略不计。然而,硬盘的使用情况却大不相同
pickle3使用7868672字节
pickle4使用16868672字节
那不是理由。我继续挖掘。读完后,我大致了解了协议
协议3的元组(1,2,3,4,5,6,7)
0: \x80 PROTO 3
2: ( MARK
3: K BININT1 1
5: K BININT1 2
7: K BININT1 3
9: K BININT1 4
11: K BININT1 5
13: K BININT1 6
15: K BININT1 7
17: t TUPLE (MARK at 2)
18: q BINPUT 0
20: . STOP
协议4的元组(1,2,3,4,5,6,7)
0: \x80 PROTO 4
2: \x95 FRAME 18
11: ( MARK
12: K BININT1 1
14: K BININT1 2
16: K BININT1 3
18: K BININT1 4
20: K BININT1 5
22: K BININT1 6
24: K BININT1 7
26: t TUPLE (MARK at 11)
27: \x94 MEMOIZE
28: . STOP
协议3的解钩器在读取到位置17之前无法知道数据的长度
对于方案4,从位置2到位置18,有一个标题显示长度
然而,我仍然不明白为什么我要支付这个价格(在极端情况下几乎是硬盘使用量的两倍),但速度是相同的或可能更慢?你在酸洗INT。对于这样一个简单的数据类型,事先知道结构的大小是没有好处的。对于更复杂的结构,了解帧大小可以极大地提高处理速度。此外,协议4解除了64位系统的许多限制。政治公众人物不清楚为什么采取这种方法吗?这与读取性能有关,特别是对于包含许多小值的更复杂结构。你的性能测试没有考虑到这一点;你写和读。谢谢你的评论。政治公众人物真的很清楚。我认为新协议意味着自由优化。现在我知道我错了。顺便说一句,将协议3和协议4结合起来是否更好?为了让它更明显:您正在编写单独的小pickle,这意味着您完全绕过了这里的帧优势。如果你写了一个带有整数列表的pickle,你就可以利用框架,但是你现在只是在蹒跚学步。你的代码中有一个bug。在pickle4案例中,您仍然关闭pickle3而不是pickle4。