objeto guardar ejemplos dumps datacamp cpickle archivo python performance pickle

guardar - Cómo reducir el tiempo necesario para cargar un archivo pickle en python



python pickle ejemplos (3)

He tenido buenos resultados en la lectura de archivos enormes (por ejemplo: ~ 750 MB igraph object - un archivo binario pickle) utilizando cPickle. Esto se logró simplemente envolviendo la llamada de carga de salmuera como se menciona here

Un fragmento de ejemplo en tu caso sería algo como:

import timeit import cPickle as pickle import gc def load_cpickle_gc(): output = open(''myfile3.pkl'', ''rb'') # disable garbage collector gc.disable() mydict = pickle.load(output) # enable garbage collector again gc.enable() output.close() if __name__ == ''__main__'': print "cPickle load (with gc workaround): " t = timeit.Timer(stmt="pickle_wr.load_cpickle_gc()", setup="import pickle_wr") print t.timeit(1),''/n''

Seguramente, podría haber formas más adecuadas de realizar la tarea, sin embargo, esta solución reduce el tiempo requerido drásticamente. (Para mí, se redujo de 843.04s a 41.28s, alrededor de 20x)

He creado un diccionario en python y me he volcado en pickle. Su tamaño fue de 300MB. Ahora, quiero cargar el mismo pepinillo.

output = open(''myfile.pkl'', ''rb'') mydict = pickle.load(output)

Cargar este pepinillo lleva alrededor de 15 segundos . ¿Cómo puedo reducir este tiempo?

Especificación de hardware: Ubuntu 14.04, 4 GB de RAM

El siguiente código muestra cuánto tiempo se tarda en volcar o cargar un archivo usando json, pickle, cPickle.

Después del volcado, el tamaño del archivo sería de alrededor de 300MB.

import json, pickle, cPickle import os, timeit import json mydict= {all values to be added} def dump_json(): output = open(''myfile1.json'', ''wb'') json.dump(mydict, output) output.close() def dump_pickle(): output = open(''myfile2.pkl'', ''wb'') pickle.dump(mydict, output,protocol=cPickle.HIGHEST_PROTOCOL) output.close() def dump_cpickle(): output = open(''myfile3.pkl'', ''wb'') cPickle.dump(mydict, output,protocol=cPickle.HIGHEST_PROTOCOL) output.close() def load_json(): output = open(''myfile1.json'', ''rb'') mydict = json.load(output) output.close() def load_pickle(): output = open(''myfile2.pkl'', ''rb'') mydict = pickle.load(output) output.close() def load_cpickle(): output = open(''myfile3.pkl'', ''rb'') mydict = pickle.load(output) output.close() if __name__ == ''__main__'': print "Json dump: " t = timeit.Timer(stmt="pickle_wr.dump_json()", setup="import pickle_wr") print t.timeit(1),''/n'' print "Pickle dump: " t = timeit.Timer(stmt="pickle_wr.dump_pickle()", setup="import pickle_wr") print t.timeit(1),''/n'' print "cPickle dump: " t = timeit.Timer(stmt="pickle_wr.dump_cpickle()", setup="import pickle_wr") print t.timeit(1),''/n'' print "Json load: " t = timeit.Timer(stmt="pickle_wr.load_json()", setup="import pickle_wr") print t.timeit(1),''/n'' print "pickle load: " t = timeit.Timer(stmt="pickle_wr.load_pickle()", setup="import pickle_wr") print t.timeit(1),''/n'' print "cPickle load: " t = timeit.Timer(stmt="pickle_wr.load_cpickle()", setup="import pickle_wr") print t.timeit(1),''/n''

Salida:

Json dump: 42.5809804916 Pickle dump: 52.87407804489 cPickle dump: 1.1903790187836 Json load: 12.240660209656 pickle load: 24.48748306274 cPickle load: 24.4888298893

He visto que cPickle toma menos tiempo para volcar y cargar, pero cargar un archivo todavía toma mucho tiempo .


Si está intentando almacenar el diccionario en un solo archivo, es el tiempo de carga para el archivo grande lo que lo está ralentizando. Una de las cosas más fáciles que puede hacer es escribir el diccionario en un directorio en el disco, con cada entrada del diccionario como un archivo individual . Luego, puede hacer que los archivos sean decapados y no seleccionados en varios subprocesos (o mediante multiprocesamiento). Para un diccionario muy grande, esto debería ser mucho más rápido que leer desde y hacia un solo archivo, independientemente del serializador que elija. Hay algunos paquetes como klepto y joblib que ya hacen mucho (si no todos los anteriores) por ti. Revisaría esos paquetes. (Nota: soy el autor de klepto . Consulte https://github.com/uqfoundation/klepto ).


Trate de usar la biblioteca json lugar de pickle . Esta debería ser una opción en su caso porque está tratando con un diccionario que es un objeto relativamente simple.

Según este sitio web ,

JSON es 25 veces más rápido en lectura (cargas) y 15 veces más rápido en escritura (volcados).

Consulte también esta pregunta: ¿Qué es más rápido: cargar un objeto de diccionario encurtido o cargar un archivo JSON en un diccionario?

La actualización de Python o el uso del módulo de marshal con una versión fija de Python también ayuda a aumentar la velocidad ( código adaptado de aquí ):

try: import cPickle except: import pickle as cPickle import pickle import json, marshal, random from time import time from hashlib import md5 test_runs = 1000 if __name__ == "__main__": payload = { "float": [(random.randrange(0, 99) + random.random()) for i in range(1000)], "int": [random.randrange(0, 9999) for i in range(1000)], "str": [md5(str(random.random()).encode(''utf8'')).hexdigest() for i in range(1000)] } modules = [json, pickle, cPickle, marshal] for payload_type in payload: data = payload[payload_type] for module in modules: start = time() if module.__name__ in [''pickle'', ''cPickle'']: for i in range(test_runs): serialized = module.dumps(data, protocol=-1) else: for i in range(test_runs): serialized = module.dumps(data) w = time() - start start = time() for i in range(test_runs): unserialized = module.loads(serialized) r = time() - start print("%s %s W %.3f R %.3f" % (module.__name__, payload_type, w, r))

Resultados:

C:/Python27/python.exe -u "serialization_benchmark.py" json int W 0.125 R 0.156 pickle int W 2.808 R 1.139 cPickle int W 0.047 R 0.046 marshal int W 0.016 R 0.031 json float W 1.981 R 0.624 pickle float W 2.607 R 1.092 cPickle float W 0.063 R 0.062 marshal float W 0.047 R 0.031 json str W 0.172 R 0.437 pickle str W 5.149 R 2.309 cPickle str W 0.281 R 0.156 marshal str W 0.109 R 0.047 C:/pypy-1.6/pypy-c -u "serialization_benchmark.py" json int W 0.515 R 0.452 pickle int W 0.546 R 0.219 cPickle int W 0.577 R 0.171 marshal int W 0.032 R 0.031 json float W 2.390 R 1.341 pickle float W 0.656 R 0.436 cPickle float W 0.593 R 0.406 marshal float W 0.327 R 0.203 json str W 1.141 R 1.186 pickle str W 0.702 R 0.546 cPickle str W 0.828 R 0.562 marshal str W 0.265 R 0.078 c:/Python34/python -u "serialization_benchmark.py" json int W 0.203 R 0.140 pickle int W 0.047 R 0.062 pickle int W 0.031 R 0.062 marshal int W 0.031 R 0.047 json float W 1.935 R 0.749 pickle float W 0.047 R 0.062 pickle float W 0.047 R 0.062 marshal float W 0.047 R 0.047 json str W 0.281 R 0.187 pickle str W 0.125 R 0.140 pickle str W 0.125 R 0.140 marshal str W 0.094 R 0.078

Python 3.4 utiliza el protocolo 3 de pickle como predeterminado , que no dio ninguna diferencia en comparación con el protocolo 4. Python 2 tiene el protocolo 2 como el protocolo más alto de pickle (seleccionado si se proporciona un valor negativo al volcado), que es dos veces más lento que el protocolo 3.