Paraleliza un generador pesado con operación de E/S.
Tengo un proyecto que estoy considerando hacer asíncrono debido a su alto costo y tiempo de ejecución.
En este proyecto tengo un generador que genera alrededor de varios millones de datos.
def generate_data():
while True:
yield data
# break if condition fulfilled
Los datos generados luego se escriben en un archivo CSV, fila por fila.
def _to_csv(data):
temp = io.StringIO()
csv_writer = csv.writer(
temp, delimiter=",", quotechar="'", quoting=csv.QUOTE_MINIMAL)
for row in data:
csv_writer.writerow([*row])
return temp
Los datos se escriben tan pronto como se obtienen.
¿Cuál sería el mejor enfoque para la asincronía? He intentado usar asyncio.as_completed
en el generador y devuelve “async_generator not an iterator” y async for in data
(pero tengo entendido que esto no paraleliza, solo permite una operación sin bloqueo). ¿Sería suficiente sin asincronía? ¿Qué hay de la multiprocesamiento?
davy.ai
Dada la larga duración del proyecto y el costo general, podría ser beneficioso explorar enfoques asíncronos para mejorar el rendimiento. Sin embargo, el enfoque actual basado en generadores no se puede usar directamente con asyncio debido a que no es un iterador.
Una opción podría ser reescribir el generador como un iterador asíncrono utilizando la sintaxis
async def
y la instrucciónyield
:Aquí,
obtener_datos_asincronos()
debería ser una función asíncrona que recupere los datos. Esto permitiría que el generador se use conasync for
para procesar los datos generados de forma asíncrona.Alternativamente, se podría utilizar el multiprocesamiento para paralelizar la generación de datos y las tareas de escritura entre múltiples procesos. Esto requeriría dividir la generación de datos en tareas separadas que puedan ser realizadas por diferentes procesos, y luego combinar los resultados posteriormente. El módulo
multiprocessing
proporciona varios mecanismos para la comunicación y sincronización entre procesos, comoQueue
yEvent
.En última instancia, la elección entre enfoques asíncronos y de multiprocesamiento dependería de las características específicas del proyecto y de los recursos disponibles. Los enfoques asíncronos pueden ser más adecuados para tareas ligadas a E/S, mientras que el multiprocesamiento puede ser mejor para tareas ligadas a la CPU. También podría valer la pena considerar un enfoque híbrido que combine ambas técnicas.