es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , , ,

Answer

  1. Avatar for 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ón yield:

    async def generar_datos():
        while True:
            yield await obtener_datos_asincronos()
            # romper si se cumple la condición
    

    Aquí, obtener_datos_asincronos() debería ser una función asíncrona que recupere los datos. Esto permitiría que el generador se use con async 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, como Queue y Event.

    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.

Comments are closed.