我注意到加载带有pickle的5000个对象的字典需要很长时间(分钟) - 但是加载5000个实体的文件的json需要很短的时间(秒)。我知道在一般情况下,对象会带来一些开销 - 而在OOP中,与跟踪这些对象相关的开销是使用它们的便利性的一部分。但是为什么加载酸洗物体需要很长时间。引擎盖下发生了什么?序列化对象与仅仅将数据写入文件相关的成本是多少?酸洗是否将对象恢复到内存中的相同位置? (也许将其他物体移开)。如果序列化加载速度较慢(至少是pickle),那么它的好处是什么?
答案 0 :(得分:3)
假设您使用的是Python 2.7标准pickle
和json
模块......
pickle
模块的纯Python实现,尽管可以使用更快的C实现。 http://docs.python.org/2/library/pickle.html json
模块的优化C实现:http://docs.python.org/dev/whatsnew/2.7.html 因此,您基本上将纯Python解串器与优化的C解串器进行比较。即使序列化格式相同,也不公平比较。
答案 1 :(得分:1)
对特定对象的序列化进行了速度比较,比较了JSON和pickle以及cPickle。每种格式的每个对象的速度都不同。 JSON通常比泡菜快,而且你经常听不到使用泡菜因为它不安全。安全问题以及一些速度滞后的原因是,pickle实际上并没有序列化非常多的数据 - 而是序列化一些数据和一堆指令,其中指令用于组装python对象。如果你曾经查看过dis
模块,你会看到pickle用于每个对象的指令类型。像json一样,cPickle不是纯python,并且利用优化的C,所以它通常更快。
酸洗应占用较少的空间,通常比存储对象本身 - 通常,一些指令集可能非常大。 JSON往往更小......并且是人类可读的...但是,因为json将所有内容存储为人类可读的字符串......它不能像pickle和cPickle一样序列化许多不同类型的对象。因此,权衡是json的“安全性”(或不灵活性,取决于你的观点)和湖南可读性与泡菜相比,它可以序列化更广泛的对象。
选择pickle(超过json)的另一个好理由是你可以轻松扩展pickle,这意味着你可以注册一个新方法来序列化pickle不知道如何pickle的对象。 Python为您提供了几种方法...... __getstate__
和__setstate__
以及copy_reg
方法。使用这些方法,您会发现人们已经扩展了pickle来序列化大多数python对象,例如dill
。
Pickling不会将对象恢复到同一个内存位置。但是,它确实将对象重建为与腌制时相同的状态(通常)。如果你想看看人们腌制的原因,请看一下:
Python serialization - Why pickle?
http://nbviewer.ipython.org/gist/minrk/5241793
http://matthewrocklin.com/blog/work/2013/12/05/Parallelism-and-Serialization/