Solo una palabra sobre cómo sacar conclusiones (incorrectas) de cualquiera de los comandos de medición de rendimiento mencionados en las respuestas. Hay una serie de dificultades que deben tenerse en cuenta además de mirar el tiempo de invocación de una función o comando (personalizado).
Sjoemelsoftware
'Sjoemelsoftware' votó la palabra holandesa del año 2015
Sjoemelen significa trampa, y la palabra sjoemelsoftware surgió debido al escándalo de emisiones de Volkswagen. La definición oficial es "software utilizado para influir en los resultados de las pruebas".
Personalmente, creo que " Sjoemelsoftware " no siempre se crea deliberadamente para engañar a los resultados de las pruebas, pero podría originarse en una situación práctica que sea similar a los casos de prueba como se muestra a continuación.
Como ejemplo, el uso de los comandos de medición de rendimiento enumerados, Language Integrated Query (LINQ) (1) , a menudo se califica como la forma más rápida de hacer algo y, a menudo, ¡pero ciertamente no siempre! Cualquiera que mida un aumento de velocidad de un factor 40 o más en comparación con los comandos nativos de PowerShell, probablemente esté midiendo o sacando una conclusión incorrecta.
El punto es que algunas clases .Net (como LINQ) usan una evaluación diferida (también conocida como ejecución diferida (2) ). Lo que significa que cuando se asigna una expresión a una variable, parece que se hace casi de inmediato, ¡pero de hecho todavía no procesó nada!
Supongamos que su fuente de puntos. .\Dosomething.ps1
tiene su comando que tiene una expresión de PowerShell o una expresión de Linq más sofisticada (para facilitar la explicación, he incrustado directamente las expresiones directamente en Measure-Command
):
$Data = @(1..100000).ForEach{[PSCustomObject]@{Index=$_;Property=(Get-Random)}}
(Measure-Command {
$PowerShell = $Data.Where{$_.Index -eq 12345}
}).totalmilliseconds
864.5237
(Measure-Command {
$Linq = [Linq.Enumerable]::Where($Data, [Func[object,bool]] { param($Item); Return $Item.Index -eq 12345})
}).totalmilliseconds
24.5949
El resultado parece obvio, el último comando de Linq es aproximadamente 40 veces más rápido que el primer comando de PowerShell . Desafortunadamente, no es tan simple ...
Vamos a mostrar los resultados:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
Como era de esperar, los resultados son los mismos, pero si ha prestado mucha atención, habrá notado que tomó mucho más tiempo mostrar los $Linq
resultados que los $PowerShell
resultados.
Midamos específicamente eso solo recuperando una propiedad del objeto resultante:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
¡Le tomó alrededor de un factor 90 más tiempo recuperar una propiedad del $Linq
objeto que el $PowerShell
objeto y eso fue solo un objeto!
Observe también otro error: si lo vuelve a hacer, ciertos pasos pueden aparecer mucho más rápido que antes, esto se debe a que algunas de las expresiones se han almacenado en caché.
En pocas palabras, si desea comparar el rendimiento entre dos funciones, deberá implementarlas en su caso usado, comenzar con una nueva sesión de PowerShell y basar su conclusión en el rendimiento real de la solución completa.
(1) Para obtener más antecedentes y ejemplos sobre PowerShell y LINQ, le recomiendo este sitio: PowerShell de alto rendimiento con LINQ
(2) Creo que hay una pequeña diferencia entre los dos conceptos, ya que con la evaluación diferida el resultado se calcula cuando es necesario según lo previsto ejecución diferida donde el resultado se calcula cuando el sistema está inactivo