Lors de l'écriture d'un script PowerShell, deux options sont disponibles:

  1. Appelez une cmdlet
  2. Utilisez la bibliothèque de classes .NET Framework

En arrière-plan, les applets de commande utilisent plus que probablement la bibliothèque .NET.

Lequel des deux est préférable d'utiliser dans un script Powershell, en termes de performances?

J'ai tendance à mieux aimer l'utilisation directe de la bibliothèque .NET car elle est plus proche de C #.

4
Spack 20 avril 2017 à 16:49

3 réponses

Meilleure réponse

Lors de l'écriture d'un script Powershell, deux options sont disponibles:

  1. Appeler une applet de commande
  2. Utiliser la bibliothèque de classes .NET Framework

TBH, je pense que c'est une simplification excessive de ce qu'est PowerShell .

La première chose à noter est que PowerShell (l'API et l'application hôte powershell.exe) est implémenté dans .NET en premier lieu, donc par définition, tout dans PowerShell "utilise .NET" .

Une applet de commande, par exemple, est en fait un objet .NET - jetez un œil à l'objet CmdletInfo retourné par Get-Command:

PS C:\> (Get-Command Get-Command) |Format-List Name,CommandType,DLL,ImplementingType


Name             : Get-Command
CommandType      : Cmdlet
DLL              : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad36
                   4e35\System.Management.Automation.dll
ImplementingType : Microsoft.PowerShell.Commands.GetCommandCommand

Jetez un œil au type d'implémentation Microsoft.PowerShell.Commands.GetCommandCommand - c'est juste une classe .NET ordinaire - lorsque vous émettez la commande Get-Command, powershell crée une instance de cette classe, appelle des méthodes bien définies, qui ensuite dans turn appelle les méthodes .NET qui effectuent le travail réel.


Toute la philosophie derrière PowerShell (ou Monad, comme on l'appelait à l'origine), est ce développement il vaut mieux passer du temps à se concentrer sur de petites unités / fonctions autonomes qui font bien une chose (une monade dans la conception originale), tout comme la philosophie originale des utilitaires UNIX.

L'idée est qu'une fois que vous avez un cadre en place pour coupler ces unités ensemble, vous pouvez virtuellement composer n'importe quel programme en connectant les unités les plus simples.

La matérialisation de cette idée est la cmdlet - elle a des comportements bien définis pour la liaison d'entrée qui vous permettent de composer des pipelines :

Get-AThing | Filter-TheThing | Write-ToAFile C:\path\to\file\name.ext

À mon humble avis, un pipeline comme celui-ci est moyen plus lisible que par exemple:

[System.IO.File]::WriteAllText('C:\path\to\file\name.ext', [System.Linq.Enumerable]::Select([Thing]::EnumerateThings(),{param([thing]$in) $in -eq $someCriteria}))

C'est subjectif, mais ce que j'essaie de comprendre, c'est que vous vous trompez en tirant parti de certaines fonctionnalités de base que PowerShell fournit gratuitement si vous abandonnez les applets de commande par le côté.


Maintenant, pour la question réelle: oui, appeler directement une seule méthode .NET est plus rapide et entraîne moins de frais généraux que d'appeler une applet de commande, ce qui oblige PowerShell à exécuter du code supplémentaire pour finalement simplement encapsuler le même appel de méthode .NET.

Cela étant dit, si vous exécutez une version plus récente de PowerShell (4.0,5.0,5.1 ou 6.0), la surcharge sera négligeable dans de nombreux cas.

Par exemple, la lecture d'un fichier à partir d'un disque est des ordres de grandeur plus lente que la résolution d'une chaîne d'appels de méthode .NET qui sont déjà en mémoire (ce que PowerShell fait de manière transparente pour vous), simplement parce que le déplacement d'électrons d'un disque en rotation à travers un disque contrôleur et un bus mémoire en mémoire est une opération limitée par la vitesse de la lumière.

Ma stratégie personnelle d'optimisation des performances consiste à examiner les algorithmes / routines et les structures de données que j'utilise, bien avant de commencer à envisager une applet de commande par rapport à un appel de méthode direct.

Si je fais quelque chose de stupide qui oblige mon script à nécessiter 10 fois plus de cycles de processeur pour calculer, cela n'aidera pas à essayer de chasser la surcharge marginale.

Si vous avez atteint la limite avec cette tactique, envisagez d'écrire votre applet de commande en C # ou VB.NET - le code compilé est (presque) toujours plus rapide que le code interprété :-)

18
Mathias R. Jessen 20 avril 2017 à 23:25

La différence entre les deux devrait être minime. L'applet de commande appellera la méthode .NET Framework et le comportement sera donc le même.

Vous pouvez donc constater des améliorations de performances extrêmement mineures en n'utilisant pas les applets de commande; mais ce sera négligeable.

Pourquoi ne pas considérer ce qui lit le mieux et s'en tenir à cela?

2
Robin Cox 20 avril 2017 à 14:06

Pour moi, après avoir utilisé les deux, le choix se résume vraiment à la maintenance du code. Les applets de commande scriptées facilitent la maintenance du code qui gère les classes et la recompilation et la publication structurées.

Les applets de commande scriptées sont mon choix à chaque fois, sauf si la vitesse de traitement est critique.

0
Peter Mortensen 28 déc. 2018 à 13:01