Add to Technorati Favorites
Welcome to ThePowerShellGuy.com Sign in | Join | Help

PowerShell Performance Series Part 1 (Warming Up)

This is the first part of a ( Multi-Blog ) series about PowerShell Performance.

In a former post, I mentioned about the task Brandon took up : PowerShell + S.DS.Protocols Versus AdFind… in this quest, preparing for his next step, the following issue came up :

What is the Quickest and most efficient way to create custom objects?

This is an important one, for PowerShell output we want objects back not text, to make the information easy to consume  part of the whole point of the exercise, but I'm sure brandon will talk about that in his series.

So let's get back to the performance, creating  custom objects is used often in cases we need to transform text into structured data, ( for some nice examples see my TextScraping series on this blog. )

In most cases for PowerShell scripts the speed is not the most important part, hence I never did any optimizing in the TextScraping series , but in Brandon's case when you have a lot of results you need to convert to Objects this is a crucial part.

In the past me and some other guys did a lot of performance testing on PowerShell V1 , and tried different coding methods, using raw .NET etc. and compared them, mostly while discussing them on IRC ( #PowerShell on FreeNode )

Brandon's question on the MVP list, combined with the CTP2 that has a lot of performance improvement got us going again as well on the list, IRC as now on our blog's as some nice results came up.

Me, Karl Prosser , Jaykul, Brandon of course, ( and anyone that wants to join on IRC , blog or elsewhere )   are for example testing :

  • Using the pipeline
  • Cmdlets
  • Raw .NET
  • Function calls
  • Cmdlet calls
  • V1 agains V2
  • all else that comes up.

And we will post some of the results to our blogs, as not only some might surprise you, but also as they can help you to pick the right solution for the right Task.

As New-Object , came out as the main bottleneck Karl made some .NET tests in PowerShell V1 that he will post on his blog later, but as I could easy test this in V2 by using Add-Type ( See . PowerShell V2 CTP2 : making Custom Enums using add-Type and Jeffrey Snover's post about it on the PowerShell team blog. for a bit more information.

I used the same method to make my own "Object Generator" Class to create new custom objects in PowerShell V2 CTP, and compared using that class to "generate" the Objects agains using the new-Object Cmdlet

$class = @"
    public static class ObjGen
    {
        public static System.Management.Automation.PSObject GetPSObject (){return new System.Management.Automation.PSObject(); }
    }
"@

add-type $class

1..10000 |% {[ObjGen]::GetPSObject()}
1..10000 |% {new-object PSObject}

h | select com*,{[datetime]$_.EndExecutionTime - [datetime]$_.StartExecutionTime}

if you paste this code in a PowerShell CTP2 console you get results like this :

1..10000 |% {[ObjGen]::GetPSObject()}                       00:00:03.8390000
1..10000 |% {new-object PSObject}                           00:00:06.6640000

for($i=0;$i -lt 10000;$i++ ) { [ObjGen]::GetPSobject() }    00:00:03.0840000

you see a big time gain , but it was way less as Karl's results (in 10 X difference range), but we could only compare difference as we where on different machines, Karl is going to set up 2 identical VM's with PowerShell version1 on one, and the PowerShell CTP2 on the other to give better comparisons, so lookout for more info about this on Karl's blog later (I will link them here).

another interesting example that Karl throw up on the IRC Channel, and that is usable on PowerShell Version 1.0 and on PowerShell CTP2

function dummy { }

1..50000 | % { dummy }
1..50000 | % { $obj = 1 }
for($i = 0; $i -lt 50000;$i++ ) { dummy }
for($i = 0; $i -lt 50000;$i++ ) { $obj = 1 }
1..50000 |  &{ process {dummy} }
function k% ([scriptblock]$sb){process {&$sb }}
1..50000 | K% { dummy }

h | select com*,{[datetime]$_.EndExecutionTime - [datetime]$_.StartExecutionTime}

My results on PowerShell CTP2 are this :

function dummy { }                                          00:00:00.0030000
1..50000 | % { dummy }                                      00:00:05.1140000
1..50000 | % { $obj = 1 }                                   00:00:03.9240000
for($i = 0; $i -lt 50000;$i++ ) { dummy }                   00:00:01.1110000
for($i = 0; $i -lt 50000;$i++ ) { $obj = 1 }                00:00:00.1220000
1..50000 |  &{ process {dummy} }                            00:00:01.4830000
function k% ([scriptblock]$sb){process {&$sb }}             00:00:00
1..50000 | K% { dummy }                                     00:00:08.7700000

If you have PowerShell Version 1.0 running paste in the same Lines in the PowerShell console and compare them with mine.

Call for Action !! : Paste the code above into a PowerShell V1 or CTP2 console also and post your results in the Comments indicating what version you did use , would be nice to compare results.

*Edit* I got this by mail from Doug Finke ( Development in a Blink )

Your comments are disabled.

My machine is 2GB dual core running Vista as the host and has Version 1 PowerShell

Version 2 CTP2 is an XP VPC.

image

Thanks Doug ! ,

and for the comments I had to disable anonymous comments because of to much spam, but you can leave comments if registered (very simple and no personal data needed)

to be continued ;-)

Enjoy,

Greetings /\/\o\/\/

Published Wednesday, June 11, 2008 6:13 PM by MoW

Comments

# Live PowerShell With Karl Prosser » Blog Archive » Getting serious about performance in PowerShell.

# Live PowerShell with Karl Prosser (Mirror) » Blog Archive » Getting serious about performance in PowerShell.

# re: PowerShell Performance Series Part 1 (Warming Up)

Using a physical machine:

Windows XP SP2, 2.8 GHz

Powershell v1.0

Duration   Average Commmand

--------   ------- --------

1:01.09375 0.00122 1..50000 | % { dummy }

0:08.40625 0.00017 1..50000 | % { $obj = 1 }

0:45.45312 0.00091 for($i = 0; $i -lt 50000;$i++ ) { dummy }

0:00.39062 0.00001 for($i = 0; $i -lt 50000;$i++ ) { $obj = 1 }

0:47.26562 0.00095 1..50000 |  &{ process {dummy} }

0:00.00000 0.00000 function k% ([scriptblock]$sb){process {&$sb }}

1:22.89062 0.00166 1..50000 | K% { dummy }

Thursday, June 12, 2008 1:02 PM by jasonmarcher

# re: PowerShell Performance Series Part 1 (Warming Up)

function dummy { }                                      00:00:00.0156713

1..50000 | % { dummy }                                  00:00:40.0245002

1..50000 | % { $obj = 1 }                               00:00:05.8767375

for($i = 0; $i -lt 50000;$i++ ) { dummy }               00:00:32.0791511

for($i = 0; $i -lt 50000;$i++ ) { $obj = 1 }            00:00:00.2820834

1..50000 |  &{ process {dummy} }                        00:00:33.5679246

function k% ([scriptblock]$sb){process {&$sb }}         00:00:00

1..50000 | K% { dummy }                                 00:01:01.4377861

Thursday, June 12, 2008 6:17 PM by dmcgill50

# Live PowerShell With Karl Prosser » Blog Archive » generating a "PropertyBag" aka PScustomObject in C#

# Live PowerShell with Karl Prosser (Mirror) » Blog Archive » generating a "PropertyBag" aka PScustomObject in C#

# PowerShell Performance Series Part 2 (.NET method call not always faster as PowerShell shortcut)

  Continuing  on from Karl's post's : Fast New PSCustomObject. generating a "PropertyBag"

Sunday, June 15, 2008 11:14 AM by The PowerShell Guy

# PowerShell Performance Series Part 4 (Version 1.0 wins this round ?)

I finally installed two simular VM's, one with PowerShell Version 1.0 and the other one with PowerShell

Monday, June 16, 2008 2:03 PM by The PowerShell Guy
Anonymous comments are disabled