joblib和pickle有哪些不同的用例?


81

背景:我刚刚开始使用scikit-learn,并在页面底部阅读了关于joblib和pickle的信息

使用joblib替换pickle(joblib.dump和joblib.load)可能会更有趣,这在大数据上效率更高,但只能在磁盘而不是字符串中进行酸洗。

我阅读了有关Pickle的问答,Python的Pickle 常见用例,想知道这里的社区是否可以共享joblib和pickle之间的差异?一个人何时应该使用另一个?

Answers:


90
  • 通常,joblib在大型numpy数组上的速度明显要快得多,因为它对numpy数据结构的数组缓冲区有特殊的处理。要查找实现细节,您可以查看源代码。它还可以在使用zlib或lz4进行酸洗时动态压缩这些数据。
  • joblib还可以在加载时对未压缩的joblib腌制numpy数组的数据缓冲区进行内存映射,从而可以在进程之间共享内存。
  • 如果您不腌制大型的numpy数组,那么常规的腌制可能会显着提高,尤其是在大型的小型python对象集合(例如大量的str对象)上,因为标准库的pickle模块是在C中实现的,而joblib是纯python。
  • 由于PEP 574(Pickle协议5)已在Python 3.8中合并,因此使用标准库对大型numpy数组进行腌制现在效率更高(在内存方面和cpu方面)。在这种情况下,大型阵列意味着4GB或更多。
  • 但是joblib在Python 3.8中仍然有用,可以在内存映射模式下使用加载具有嵌套numpy数组的对象mmap_mode="r"

1
非常感谢!这是有帮助的。
msunbot 2012年

1
这是否意味着我们应该使用Joblibover PickleJoblib我们应该考虑哪些缺点?我最近才听说Joblib过,这听起来很有趣。
Catbuilts

1
我已经用标准库中的缺点和新内容更新了我的答案。
ogrisel

2
Joblib在解析期间是否还会执行任意代码?(不安全)
Mr-Programs

这很难通读所有的“注意...”并获得单行摘要:在3.8中写入大型numpy数组时,joblib的速度快X倍,X大约是多少?和阅读?而pickle编写许多小的Python对象的速度大约快了Y倍,什么是Y?和阅读?另外,相对压缩率/文件大小是多少?
smci

12

感谢Gunjan给我们这个脚本!我为Python3结果修改了它

#comapare pickle loaders
from time import time
import pickle
import os
import _pickle as cPickle
from sklearn.externals import joblib

file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'database.clf')
t1 = time()
lis = []
d = pickle.load(open(file,"rb"))
print("time for loading file size with pickle", os.path.getsize(file),"KB =>", time()-t1)

t1 = time()
cPickle.load(open(file,"rb"))
print("time for loading file size with cpickle", os.path.getsize(file),"KB =>", time()-t1)

t1 = time()
joblib.load(file)
print("time for loading file size joblib", os.path.getsize(file),"KB =>", time()-t1)

time for loading file size with pickle 79708 KB => 0.16768312454223633
time for loading file size with cpickle 79708 KB => 0.0002372264862060547
time for loading file size joblib 79708 KB => 0.0006849765777587891

Gunjan使用了1154320653 KB泡菜文件。更大的文件可以对joblib有所帮助吗?
guiferviz

请在显示性能数字时请务必声明您的Python版本。2.6?2.7?3.6?3.7?更好的是,报告相对数字joblib,pickle和cPickle。另外,修复Gunjan的1.1 GB而不是1.1 TB的错误
smci

8

我遇到了同样的问题,所以我尝试了这个问题(使用Python 2.7),因为我需要加载一个大型的pickle文件

#comapare pickle loaders
from time import time
import pickle
import os
try:
   import cPickle
except:
   print "Cannot import cPickle"
import joblib

t1 = time()
lis = []
d = pickle.load(open("classi.pickle","r"))
print "time for loading file size with pickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1

t1 = time()
cPickle.load(open("classi.pickle","r"))
print "time for loading file size with cpickle", os.path.getsize("classi.pickle"),"KB =>", time()-t1

t1 = time()
joblib.load("classi.pickle")
print "time for loading file size joblib", os.path.getsize("classi.pickle"),"KB =>", time()-t1

的输出是

time for loading file size with pickle 1154320653 KB => 6.75876188278
time for loading file size with cpickle 1154320653 KB => 52.6876490116
time for loading file size joblib 1154320653 KB => 6.27503800392

根据这个作业库,这三个模块中的cPickle和Pickle模块效果更好。谢谢


1
我以为泡椒应该比泡菜快?
2016年

该基准测试是否通过python 3(默认情况下使用pickle(protocol = 3))(比python2中的默认速度更快)来完成?
2017年

3
os.path.getsize返回的字节数不是千字节,因此我们正在谈论的文件约为1.1 GB(而不是输出中的1.1 TB)
Vlad Iliescu

很棒,但是请修正输出以反映出1.1 GB而不是1.1 TB。更好的是绘制10乘幂的文件大小的比较数字,从1KB ... 10GB,对于Python版本3.6、3.7、3.8和2.7,对于joblib,pickle和cPickle。
smci
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.