Powershell cmdlet vs .NET Class

When writing a Powershell script, there are two options available:

In the background, cmdlets more than likely use the .NET library.

So the question is, which one is better to use in a Powershell script, performance wise?

I prefer using the .NET library directly as it is closer to C #.

+3


source to share


3 answers


When writing a Powershell script, there are two options available:

  • Calling a cmdlet
  • Using the .NET Framework Class Library

TBH, I think, is a gross oversimplification of what PowerShell is.

The first thing to note is that PowerShell (API and host application powershell.exe

) is implemented in .NET in the first place, so by definition everything in PowerShell "uses .NET".

The cmdlet, as an example, is actually a .NET object. Look at the CmdletInfo object returned 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

      

Look at the implementation type Microsoft.PowerShell.Commands.GetCommandCommand

- this is just a regular .NET class - when issuing a command Get-Command

, powershell instantiates this class, calls some well-defined methods, which then in turn calls .NET methods that do the actual work.


The whole philosophy behind PowerShell (or Monad as it was originally called ) is that development time is better spent focusing on the small self - components / functions that do something well (the monad in the original concept), so the same as the original philosophy of UNIX utilities.

The idea is that, once you have the structure to wire these devices together, you can almost compose any program by connecting simpler devices.

Materializing this idea is a cmdlet - it has some well-defined input binding behaviors that allow you to compose pipelines:

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

      



In my humble opinion, a pipeline like the one above is more readable than for example:

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

      

This is subjective, but what I'm trying to understand is that you are fooling yourself about using some of the core functionality that PowerShell provides for free out of the box if you pass the cmdlet using the way-side


Now, for the actual question: yes, calling one .NET method directly is faster and requires less overhead than calling a cmdlet, which in turn makes PowerShell run some extra code to end up just wrapping the same method call. NET.

If you are using a newer version of PowerShell (4.0.5.0.5.1 or 6.0), there will be little overhead in many cases.

For example, reading a file from disk is orders of magnitude slower than resolving chaining of .NET method calls that are already in memory (which is what PowerShell does transparently for you) simply because moving electrons from a spinning disk through the disk controller and bus memory to memory is an operation limited by the speed of light.

My personal performance optimization strategy is an overview of the algorithms / routines and data structures that I use, long before I started considering calling cmdlet vs. direct.

If I do something stupid that makes my script require 10x the number of CPU cycles to compute, then that doesn't help chase the marginal overhead.

If you've hit the limit with this tactic, consider writing your cmdlet in C # or VB.NET - compiled code is (almost) always faster than interpreted code :-)

+11


source


The difference between the two should be minimal. The cmdlet will call a .NET Framework method, so the behavior is the same.

Thus, you can see some minor performance improvements without using cmdlets; but it will be negligible.



Why not consider reading and sticking to it?

+2


source


For me, after using both, the choice really comes down to code maintenance. Scripted cmdlets make it easier to maintain the code that drives the classes, and there is a structured recompilation and release. Scripted cmdlets are my choice every time when processing speed is not critical.

0


source







All Articles