¿Cuáles son los diferentes casos de uso de joblib versus pickle?


81

Antecedentes: recién estoy comenzando con scikit-learn, y leo al final de la página sobre joblib, versus pickle .

puede ser más interesante usar el reemplazo de pickle de joblib (joblib.dump & joblib.load), que es más eficiente en big data, pero solo puede hacer pickle en el disco y no en una cadena

Leí estas preguntas y respuestas sobre Pickle, casos de uso comunes para pickle en Python y me pregunto si la comunidad aquí puede compartir las diferencias entre joblib y pickle. ¿Cuándo debería uno usar uno sobre otro?

Respuestas:


91
  • joblib suele ser significativamente más rápido en matrices numpy grandes porque tiene un manejo especial para los búferes de matriz de la estructura de datos numpy. Para conocer los detalles de la implementación, puede consultar el código fuente . También puede comprimir esos datos sobre la marcha durante el decapado con zlib o lz4.
  • joblib también hace posible mapear en memoria el búfer de datos de una matriz numpy sin comprimir con picking de joblib al cargarla, lo que hace posible compartir memoria entre procesos.
  • Si no selecciona encurtidos grandes matrices numpy, entonces el encurtido regular puede ser significativamente más rápido, especialmente en grandes colecciones de pequeños objetos de Python (por ejemplo, un gran dict de objetos str) porque el módulo pickle de la biblioteca estándar se implementa en C mientras que joblib es pitón puro.
  • Dado que PEP 574 (protocolo Pickle 5) se ha fusionado en Python 3.8, ahora es mucho más eficiente (en cuanto a memoria y en cpu) seleccionar matrices de gran tamaño utilizando la biblioteca estándar. Las matrices grandes en este contexto significan 4 GB o más.
  • Pero joblib aún puede ser útil con Python 3.8 para cargar objetos que tienen matrices numpy anidadas en modo mapeado en memoria con mmap_mode="r".

1
¡Muchas gracias! Esto es útil.
msunbot

1
¿Significa que deberíamos consumir Joblibmás Pickle? ¿Alguna desventaja de Joblibeso que deberíamos considerar? Me acabo de enterar Joblibrecientemente y me parece interesante.
Catbuilts

1
He actualizado mi respuesta con desventajas y cosas nuevas que suceden en la biblioteca estándar.
ogrisel

2
¿Joblib también ejecuta código arbitrario durante el análisis? (Inseguro)
Mr-Programs

Es difícil leer todo el "Tenga en cuenta que ..." y obtener el resumen de una línea: joblib es X veces más rápido para escribir matrices de números grandes en 3.8, aproximadamente ¿qué es X? y para leer y pickle es aproximadamente Y veces más rápido para escribir muchos objetos pequeños de Python, ¿qué es Y? y para leer Además, ¿cuáles son las relaciones de compresión relativas / tamaños de archivo?
smci

12

¡Gracias a Gunjan por darnos este script! Lo modifiqué para los resultados de 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 usó un archivo pickle de 1154320653 KB. ¿Podría un archivo más grande marcar la diferencia a favor de joblib?
guiferviz

Por favor, indique siempre su versión de Python cuando muestre los números de rendimiento. 2.6? 2.7? 3.6? 3,7? Mejor aún, informe los números relativos de joblib vs pickle vs cPickle. Además, corrija el error de Gunjan de 1,1 GB, no 1,1 TB
smci

8

Me encontré con la misma pregunta, así que probé esta (con Python 2.7) ya que necesito cargar un archivo pickle grande

#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

La salida para esto es

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

Según este joblib funciona mejor que el módulo cPickle y Pickle de estos 3 módulos. Gracias


1
Pensé que cpickle debería ser más rápido que pickle.
Echo

¿Este punto de referencia se realiza con python 3, que usa pickle (protocolo = 3) de forma predeterminada (que es más rápido que el predeterminado en python2)?
LearnOPhile

3
os.path.getsize devuelve bytes, no kilobytes, por lo que estamos hablando de un archivo de aproximadamente 1,1 GB (y no 1,1 TB como parece en la salida)
Vlad Iliescu

Esto es genial, pero corrija la salida para reflejar que es 1,1 GB, no 1,1 TB. Mejor aún sería trazar números comparativos para tamaños de archivos en potencias de 10 desde 1KB ... 10GB, para las versiones de Python 3.6, 3.7, 3.8 y 2.7, para joblib, pickle y cPickle.
smci
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.