Juste un mot pour tirer des conclusions (incorrectes) à partir de l'une des commandes de mesure du rendement mentionnées dans les réponses. Il y a un certain nombre d'écueils qui devraient être pris en considération en plus de regarder le temps d'invocation nu d'une fonction ou d'une commande (personnalisée).
Sjoemelsoftware
«Sjoemelsoftware» a été élu mot néerlandais de l'année 2015
Sjoemelen signifie tricherie, et le mot sjoemelsoftware a vu le jour en raison du scandale des émissions de Volkswagen. La définition officielle est "logiciel utilisé pour influencer les résultats des tests".
Personnellement, je pense que " Sjoemelsoftware " n'est pas toujours délibérément créé pour tricher les résultats des tests mais pourrait provenir de situations pratiques accommodantes qui sont similaires aux cas de test comme indiqué ci-dessous.
A titre d'exemple, en utilisant les commandes de mesure du rendement dans la liste, Query Language intégrée (LINQ) (1) , est souvent qualifié de la façon jeûné pour faire quelque chose et il est souvent, mais certainement pas toujours! Quiconque mesure une augmentation de vitesse d'un facteur 40 ou plus par rapport aux commandes PowerShell natives, mesure probablement ou tire une conclusion incorrecte.
Le fait est que certaines classes .Net (comme LINQ) utilisant une évaluation paresseuse (également appelées exécution différée (2) ). Cela signifie que lorsque vous affectez une expression à une variable, cela semble presque immédiatement être fait, mais en fait, il n'a encore rien traité!
Supposons que vous dot-source votre . .\Dosomething.ps1
commande qui a soit une expression PowerShell ou une expression Linq plus sophistiquée (pour la facilité d'explication, j'ai directement intégré les expressions directement dans le 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
Le résultat semble évident, la dernière commande Linq est environ 40 fois plus rapide que la première commande PowerShell . Malheureusement, ce n'est pas si simple ...
Voyons les résultats:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
Comme prévu, les résultats sont les mêmes mais si vous avez fait très attention, vous aurez remarqué qu'il a fallu beaucoup plus de temps pour afficher les $Linq
résultats que les $PowerShell
résultats.
Mesurons spécifiquement cela en récupérant simplement une propriété de l'objet résultant:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
Il a fallu environ un facteur 90 de plus pour récupérer une propriété de l' $Linq
objet, puis le$PowerShell
objet et ce n'était qu'un seul objet!
Notez également un autre écueil: si vous recommencez, certaines étapes peuvent apparaître beaucoup plus rapidement qu'avant, car certaines des expressions ont été mises en cache.
En résumé, si vous souhaitez comparer les performances entre deux fonctions, vous devrez les implémenter dans votre cas d'utilisation, commencer par une nouvelle session PowerShell et baser votre conclusion sur les performances réelles de la solution complète.
(1) Pour plus d'informations et d'exemples sur PowerShell et LINQ, je recommande ce site: PowerShell haute performance avec LINQ
(2) Je pense qu'il y a une différence mineure entre les deux concepts, car avec une évaluation paresseuse, le résultat est calculé au besoin en fonction de exécution différée où le résultat est calculé lorsque le système est inactif