Tengo un programa de python donde necesito cargar y deserializar un archivo pickle de 1 GB. Tarda unos buenos 20 segundos y me gustaría tener un mecanismo mediante el cual el contenido del pepinillo esté disponible para su uso. He mirado shared_memory pero todos los ejemplos de su uso parecen involucrar numpy y mi proyecto no usa numpy. ¿Cuál es la forma más fácil y limpia de lograr esto usando shared_memory o de otra manera?
Así es como estoy cargando los datos ahora (en cada ejecución):
def load_pickle(pickle_name): return pickle.load(open(DATA_ROOT + pickle_name, 'rb')) Me gustaría poder editar el código de simulación entre ejecuciones sin tener que volver a cargar el pickle. He estado jugando con importlib.reload pero realmente no parece funcionar bien para un gran programa de Python con muchos archivos:
def main(): data_manager.load_data() run_simulation() while True: try: importlib.reload(simulation) run_simulation() except: print(traceback.format_exc()) print('Press enter to re-run main.py, CTRL-C to exit') sys.stdin.readline()Esto podría ser un problema XY , cuya fuente es la suposición de que debe usar pepinillos en absoluto; son terribles de manejar debido a la forma en que administran las dependencias y son fundamentalmente una mala elección para cualquier almacenamiento de datos a largo plazo debido a eso
Para empezar, los datos financieros de origen están casi con seguridad en forma tabular, por lo que es posible solicitarlos en un formato más amigable.
Un middleware simple para deserializar y volver a serializar los pepinillos mientras tanto suavizará la transición.
input -> load pickle -> write -> outputConvertir su flujo de trabajo para usar Parquet o Feather, que están diseñados para ser eficientes para leer y escribir , casi seguramente hará una diferencia considerable en su velocidad de carga.
Más enlaces relevantes
También puede lograr esto con hickle , que usará internamente un formato HDH5, idealmente haciéndolo significativamente más rápido que pickle, sin dejar de comportarse como tal.
Una alternativa para almacenar los datos no seleccionados en la memoria sería almacenar los datos seleccionados en un ramdisk, siempre que la mayor parte de la sobrecarga provenga de las lecturas del disco. El código de ejemplo (para ejecutar en una terminal) se encuentra a continuación.
sudo mkdir mnt/pickle mount -o size=1536M -t tmpfs none /mnt/pickle cp path/to/pickle.pkl mnt/pickle/pickle.pkl Luego puede acceder al pickle en mnt/pickle/pickle.pkl . Tenga en cuenta que puede cambiar los nombres de los archivos y las extensiones a lo que desee. Si la lectura del disco no es el mayor cuello de botella, es posible que no vea un aumento de la velocidad. Si se queda sin memoria, puede intentar reducir el tamaño del ramdisk (lo configuré en 1536 mb o 1,5 gb)
Puede usar la lista compartible: por lo tanto, tendrá 1 programa de python en ejecución que cargará el archivo y lo guardará en la memoria y otro programa de python que puede tomar el archivo de la memoria. Sus datos, sean lo que sean, puede cargarlos en el diccionario y luego volcarlos como json y luego volver a cargar json. Entonces
programa1
import pickle import json from multiprocessing.managers import SharedMemoryManager YOUR_DATA=pickle.load(open(DATA_ROOT + pickle_name, 'rb')) data_dict={'DATA':YOUR_DATA} data_dict_json=json.dumps(data_dict) smm = SharedMemoryManager() smm.start() sl = smm.ShareableList(['alpha','beta',data_dict_json]) print (sl) #smm.shutdown() commenting shutdown now but you will need to do it eventuallyLa salida se verá así
#OUTPUT >>>ShareableList(['alpha', 'beta', "your data in json format"], name='psm_12abcd')Ahora en Programa2:
from multiprocessing import shared_memory load_from_mem=shared_memory.ShareableList(name='psm_12abcd') load_from_mem[1] #OUTPUT 'beta' load_from_mem[2] #OUTPUT yourdataindictionaryformatPuede buscar más aquí https://docs.python.org/3/library/multiprocessing.shared_memory.html