我正在测试 Python 3.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):
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)
Run Code Online (Sandbox Code Playgroud)
test1 标记:6.473 秒内调用 2000007 次函数
test2 标记:6.740 秒内调用 2000007 次函数
协议4比协议3稍微慢一些。这种差异可以忽略不计。然而,硬盘的使用情况确实不同。
pickle3 使用 7,868,672 字节。
pickle4 使用 16,868,672 字节。
那没有理由。我继续挖掘。读完PEP3154后,我大致了解了该协议。
对于协议 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
Run Code Online (Sandbox Code Playgroud)
对于协议 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
Run Code Online (Sandbox Code Playgroud)
协议3的unpickler在读取到位置17之前无法知道数据的长度。
对于协议 4,从位置 2 到位置 18,有一个显示长度的标题。
但是,我仍然不明白为什么我付出了代价(在极端情况下几乎是硬盘使用量的两倍)但速度相同或可能更慢?