Python 为什么Pickle协议4中的Pickle文件比协议3中的文件大两倍,而速度却没有任何提高?

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):

我正在测试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):
        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。