ForEach-Object en paralelo con PowerShell 7.0
Los “loops” o bucles, son pilares fundamentales en los lenguajes de programación, y/o scripting, en donde se utilizan ampliamente debido al componente lógico crucial permitiendo iterar a través de una colección de objetos.
PowerShell contiene el cmdlet Foreach-Object que permite realizar bucles de forma simple y directa. Su defecto: es secuencial, ya que el siguiente valor en el ciclo solo se procesa después de que el anterior haya finalizado. Pero llegó PowerShell 7.0…
Y cambió las reglas del juego. Introducido en la la versión 7.0 Beta 3, la nueva característica de Foreach-Object -Parallel permite realizar en forma simultánea operaciones utilizando de forma nativa la función del lenguaje Foreach-Object, ampliamente utilizada en nuestros scripts.
La opción Parallel en el cmdlet ForEach-Object
habilita la ejecución de un bucle ForEach-Object contra varios valores al mismo tiempo. Con una refactorización mínima, es posible agregar esta nueva funcionalidad a los bucles ForEach-Object
existentes y obtener un aumento significante de velocidad en las ejecuciones.
foreach vs ForEach-Object
Aunque el título parece un juego de palabras, es necesario aclarar las disimilitudes entre ambos usos y cuando en realidad hace la diferencia cada forma. Si bien algunas veces consideramos que usar ForEach significa estar usando ForEach-Object
como un “alias”, depende efectivamente en que momento se declara y ejecuta, ya que podemos caer en la ejecución de un PowerShell statement en vez de ejecutar el cmdlet que trabaja correctamente recibiendo datos desde un pipeline.
ForEach-Object antes
Tal como se mencionó en el párrafo anterior, ForEach-Object
está diseñado para iterar a través de objetos en un pipeline. Para demostrar esto, se define un loop sobre una colección de 10 objetos y su impresión en la consola, y midamos cuánto tiempo lleva.
ForEach-Object reloaded
¿Cómo se comportaría el mismo código utilizando ejecuciones en paralelo?
Lo que anteriormente tomó unos 10 segundos, ahora se ejecutó en menos de 3 segundos. Un dato importante a resaltar es el orden de los objetos devueltos: ya no fue ejecutado secuencialmente. Esto se debe a que está ejecutando varias operaciones a la vez y las devuelve tan pronto como se realiza. De forma predeterminada ejecuta 5 operaciones simultáneas.
Para cambiar el número predeterminado de ejecuciones “paralelas” hay que recurrir al parámetro ThrottleLimit
.
No siempre es posible utilizar esta feature, ya que algunos escenarios requerirán que la ejecución sea secuencial, por ejemplo en la transferencia de archivos: ejecuciones en paralelo pueden saturar la conexión o disminuir la velocidad .
Info adicional en el siguiente enlace: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7
Happy scripting!
Comments