【发布时间】:2012-01-20 18:58:30
【问题描述】:
我正在实现一个需要对大型对象进行序列化和反序列化的程序,因此我对pickle、cPickle 和marshal 模块进行了一些测试,以选择最佳模块。一路走来,我发现了一些非常有趣的事情:
我在字典、元组、整数、浮点数和字符串列表中使用dumps,然后使用loads(对于每个模块)。
这是我的基准测试的输出:
DUMPING a list of length 7340032
----------------------------------------------------------------------
pickle => 14.675 seconds
length of pickle serialized string: 31457430
cPickle => 2.619 seconds
length of cPickle serialized string: 31457457
marshal => 0.991 seconds
length of marshal serialized string: 117440540
LOADING a list of length: 7340032
----------------------------------------------------------------------
pickle => 13.768 seconds
(same length?) 7340032 == 7340032
cPickle => 2.038 seconds
(same length?) 7340032 == 7340032
marshal => 6.378 seconds
(same length?) 7340032 == 7340032
因此,从这些结果中我们可以看到marshal 在基准测试的转储部分非常快:
比
pickle快 14.8 倍,比cPickle快 2.6 倍。
但是,让我大吃一惊的是,marshal 在 加载 部分比 cPickle 慢得多:
比
pickle快 2.2 倍,但比cPickle慢 3.1 倍。
而对于 RAM,marshal 在加载时的性能也非常低效:
我猜想使用marshal 加载如此缓慢的原因在某种程度上与其序列化字符串的长度有关(比pickle 和cPickle 长得多)。
- 为什么
marshal转储更快而加载更慢? - 为什么
marshal序列化的字符串那么长? - 为什么
marshal的加载在 RAM 中效率如此之低? - 有没有办法提高
marshal的加载性能? - 有没有办法将
marshal快速转储与cPickle快速加载合并?
【问题讨论】:
-
你的问题是死胡同。
marshal模块并不打算用作pickle的替代品。没有关于 marshal 文件格式的官方文档,它可能会因版本而异,因此您的基准测试结果将来可能是错误的。 -
在核心,您的问题完全相同:为什么 marshal 更快?速度/内存使用是计算中通常的权衡。是的,你的问题没有用。当然,这只是我的看法。
-
不保证现在由 marshal 创建的文件可以被所有未来版本的 Python 读取。你的研究毫无意义。
标签: python performance serialization