Cómo potenciar sus flujos de trabajo de bash con GNU paralelo

GNU paralleles una herramienta de línea de comandos para ejecutar trabajos en paralelo.

paralleles impresionante y pertenece a la caja de herramientas de todo programador. Pero los documentos me parecieron un poco abrumadores al principio. Afortunadamente, puede comenzar a ser útil parallelcon solo unos pocos comandos básicos.

¿Por qué es paralleltan útil?

Comparemos la ejecución secuencial y paralela de la misma tarea de cálculo intensivo.

Imagina que tienes una carpeta de archivos de audio .wav para convertir a .flac:

Estos son archivos bastante grandes, cada uno tiene al menos un gigabyte.

Usaremos otra gran herramienta de línea de comandos, ffmpeg, para convertir los archivos. Esto es lo que necesitamos ejecutar para cada archivo.

ffmpeg -i audio1.wav audio1.flac

Escribamos un script para convertir cada uno secuencialmente:

# convert.sh ffmpeg -i audio1.wav audio1.flac ffmpeg -i audio2.wav audio2.flac ffmpeg -i audio3.wav audio3.flac ffmpeg -i audio4.wav audio4.flac ffmpeg -i audio5.wav audio5.flac

Podemos cronometrar la ejecución de un trabajo anteponiendo timeal llamar al script desde la terminal. timeimprimirá el tiempo real transcurrido durante la ejecución.

time ./convert.sh

Nuestro guión termina en poco más de un minuto.

No está mal. ¡Pero ahora ejecutémoslo en paralelo!

No tenemos que cambiar nada sobre nuestro guión. Con la -abandera, podemos canalizar nuestro script directamente a parallel. parallelejecutará cada línea como un comando separado.

parallel -a ./convert.sh

Usando parallel, nuestra conversión se ejecutó en poco más de la mitad del tiempo. ¡Agradable!

Con solo cinco archivos, esta diferencia no es tan importante. Pero con listas más grandes y tareas más largas, podemos ahorrar mucho tiempo con parallel.

Me encontré parallelmientras trabajaba con una tarea de procesamiento de datos que probablemente se habría ejecutado durante una hora o más si se hubiera realizado de forma secuencial. Con parallel, solo tomó unos minutos.

parallella energía también depende de su computadora. El Intel i7 de mi MacBook Pro tiene solo 4 núcleos. Incluso esta pequeña tarea los llevó a todos al límite:

Las computadoras más potentes pueden tener procesadores con 8, 16 o incluso 32 núcleos, lo que ofrece un enorme ahorro de tiempo mediante la paralelización de sus trabajos.

Ser útil con parallel

El otro gran beneficio de paralleles su brevedad y simplicidad. Comencemos con un script Python desagradable y conviértalo en una llamada limpia a parallel.

Aquí hay un script de Python para lograr nuestra conversión de archivos de audio:

import subprocess path = Path.home()/'my-data-here' for audio_file in list(path.glob('*.wav')): cmd = ['ffmpeg', '-i', str(audio_file), f'{audio_file.name.split(".")[0]}.flac'] subprocess.run(cmd, stdout=subprocess.PIPE)

¡Ay! En realidad, eso es mucho código en el que pensar solo para convertir algunos archivos. (Esto tarda aproximadamente 1,2 minutos en ejecutarse).

Convirtamos nuestro Python a parallel.

Llamar a un script con parallel -a

parallel -a your-script-here.sh es el buen resumen que usamos anteriormente para canalizar nuestro script bash.

Esto es genial, pero requiere que escriba el script bash que desea ejecutar. En nuestro ejemplo, todavía Escribimos cada llamada individual a ffmpegen convert.sh.

Interpolación de tuberías y cadenas con parallel

Afortunadamente, parallelnos brinda una forma de eliminarlo por convert.shcompleto.

Esto es todo lo que tenemos que ejecutar para lograr nuestra conversión:

ls *.wav | parallel ffmpeg -i {} {.}.flac

Analicemos esto.

Obtenemos una lista de todos los archivos .wav en nuestro directorio con ls *.wav. Entonces estamos canalizando ( |) esa lista a parallel.

Parallel proporciona algunas formas útiles de hacer interpolación de cadenas, por lo que nuestras rutas de archivo se ingresan correctamente.

La primera es {}, que parallelse reemplaza automáticamente con una línea de nuestra entrada.

El segundo operador es {.}, que ingresará una línea pero sin las extensiones de archivo.

Si expandimos el comando run by parallelpara nuestra primera línea de entrada, veríamos ...

ffmpeg -i audio1.wav audio1.flac

Args con Parallel

Resulta que ni siquiera necesitamos conectarnos lspara completar nuestra tarea. Podemos ir más simple aún:

parallel ffmpeg -i {} {.}.flac ::: *.wav

Los argumentos que se pasan para que parallelocurran después del comando y están separados por :::. En este caso, nuestro argumento es *.wav, que proporcionará la lista de todos los archivos .wav en nuestro directorio. Estos archivos se convierten en la entrada para nuestro paralleltrabajo ultrarrápido .

Fun fact: parallel was built by Ole Tange and published in 2011. According to him, you can use the tool for research without citing the source paper for the modest fee of 10,000 euros!

Thanks for reading!