Custom PowerShell Objects and Performance Revisited

Way back in my earlier days of blogging (Sept 2010), I wrote an article (I recommend you check this one out for more information regarded some of the older styles of custom object creation) that talked about the performance differences between a few different ways that you can create a custom PowerShell object.

At that time we were rocking PowerShell V2 and enjoying all of the great benefits that were being brought to us. Fast forward to now and we are sitting at V4 and have a new way to create a custom PowerShell object in [pscustomobject]. What this brings us is a way to finally have the speed benefits of doing PSObject…

New-Object PSObject -Property @{
Name = 'Boe'
Number = 1
ID = 007
}

…with the ability of keeping everything in the order we specify like when we use the Select-Object method:

$Object = '' | Select-Object Name, Number, ID
$Object.Name = 'Boe'
$Object.Number = 1
$Object.ID = 007

Another method which was discussed was the use of Add-Member to create objects:

$Object = New-Object PSObject
$Object | Add-Member -MemberType NoteProperty -Name Name -Value Boe -PassThru |
Add-Member -MemberType NoteProperty -Name Number -Value 1 -PassThru |
Add-Member -MemberType NoteProperty -Name ID -Value 007 -PassThru

The New Stuff

I won’t really dive any deeper into these as you can view that old blog post to catch up on the rest of that stuff, but what I will do is show off [pscustomobject] as well as take all of these for a spin again and show off the performance differences between these 4 contenders.

[pscustomobject] is pretty simple to use:

[pscustomobject]@{
    Name= 'Boe'
    Number = 1
    ID = 007
}

The best part is that it keeps its order and is pretty quick as well. Just how quick is it? Well, sit back and check out the stats when compared to the other methods. If you have read the previous blog entry, you will see that Add-Member was by far the slowest method while Select-Object and New-Object PSObject were neck and neck in speed with PSObject pulling ahead slightly for the win.

After I initially published this article, I had some suggestions on other items to include in my testing. The are New-Object PSObject –Property ([ordered@{}) and $prop=[ordered]@{};[pscustomobject]$prop (labeled [pscustomobject][ordered]). Both of these output the same type of ordered object, meaning that the order that you supply the data in the hash table is the same order that it will display on the console.

Keep in mind that this produces the exact same output as if you would use [pscustomobject] by itself.

image

So how will these newcomers compare with everything else? Let’s find out!

The Approach

If you saw the previous blog where I talk about performance, you noticed that I had a script that helped to make the determination as to what was the fastest approach. Well, this script was not exactly the best written script and had a lot of manual things going on. I’ve updated my script to make it easier to add the number of cycles (basically the number of “systems” to run against), the number of properties to have in the custom object and finally the number of times to repeat each operation. The script is available to download from the link at the end of this article if you are interested in running it yourself.

The Results

I started out at running against 10 “systems” (cycles) while creating the following sets of objects (1,5,10,25,50,100) and repeated this 5 times. I then upped the cycles to the following values and ran against each one to record the time it took each type to complete: 50,100,500,1000,5000,10000. The first list of graphs will show you everything at its own scale, meaning that the highest time for each cycle will be the max on the graph. Because this doesn’t always tell the whole store, I also included a second set of graphs that show the highest value recorded during the entire time spent running the scans (the 10000 cycle scan had the highest time taken). At the beginning, you really won’t see much of anything but as the cycles go on, you can see which approach becomes slower and slower.

So with all of that out of the way, let me show the first set of graphs that show the results of my tests.

image

image

image

image

image

image

 

Both [pscustomobject] and the [pscustomobject][ordered] approach were the fastest ones in PowerShell and for the most part are interchangeable (assuming that you are running V3/4, of course). Add-Member is definitely the slowest approach, much like it was when I first ran this test. The rest of the bunch were back and forth as far as which ones were faster at any given moment in time.  As I said previously, these numbers are all scaled to their respected highest time. The graphs below will show the scale from the 10000 Cycle run which had the highest time returned.

image

image

image

 

image

image

image

This shows that in the same scale as 10000 cycles, the level of difference in performance doesn’t really come into play until you are running against 500 systems. Of course, various outside conditions such as network latency and system performance come into play as well, but you get the idea.

Much like the tests I ran back in 2010, Select-Object and New-Object PSObject are practically neck and neck and really come down to your preference of having your properties come out in the order that they were coded (Select-Object) or having a very slight and much better looking (from a coding style) approach (PSObject).

I hope you enjoyed this article and found the information useful when it comes time to make a decision what method you wish to take. My personal take is that if you are running V3/4, then you really should be using [pscustomobject] unless you have a need to add to an existing object or add some other levels of properties to an object in which Add-Member should be used at the cost of performance. While the [pscustomobject][ordered] was on par with [pscustomobject], they are the same thing and if you want to save an extra line of code, you should look at just using [pscustomobject]@{} by itself. But in the end, it is up to you to decide what you feel may be the right choice based on your requirements.

Download Script

Technet Script Repository

This entry was posted in powershell and tagged , , . Bookmark the permalink.

4 Responses to Custom PowerShell Objects and Performance Revisited

  1. Pingback: Tell Me It Is Broken – Lazy Development

  2. Pingback: 堪称《神曲》的PowerShell自定义对象性能大比拼 | PowerShell 中文博客

  3. Pingback: Custom PowerShell Object Performance | /// stealthfield

  4. Hi Boe,

    Good stuff, thanks for collecting and presenting the stats!

    I generally stick to [pscustomobject] on the fly and on scripts that execute only on systems with PowerShell 3. Sadly, we have too many systems out there that force PowerShell v2 language on us (or worse… preclude using PowerShell remoting).

    For posting code others might use I prefer compatibility with a slight sacrifice in speed, and generally stick to the Select-Object and New-Object methods. I like the styling of New-Object better. Usually end up with something like this:

    New-Object -TypeName PSObject -Property @{
    A = 1
    B = ”Two”
    C = $something
    } | Select-Object A, B, C

    Cheers!

Leave a comment