I’ve read and heard a lot about PowerShell speed recently – that is the speed of execution of your scripts and how you can make your code faster.

The first thing to think about – and this is the one many people miss – is does the absolute speed of my PowerShell code actually matter. If I have a script that takes 5 seconds to run and it takes me 10 days effort to get that script to run in 4 seconds is that a worthwhile use of my time? If the script runs once in a while – definitely not. If it runs 1000s of times a day then probably yes.

The other thing to consider is what else you could be doing in that 10 days. You could probably solve a few problems that would save a bunch of time.

My working definition of a good script is one that works, runs in an acceptable time frame and is readable for relatively easy maintenance. Code style and anything else is just fluff.

The bit that got me thinking was the difference in speed between:

$i = 0

1..1000 | foreach {$i += $_}

$i

and

$i = 0

foreach ($j in 1..1000) {$i += $j}

$i

We actually discuss this in PowerShell in Action. The pipeline is optimised for resource usage. The foreach command is optimised for speed. You have a trade off between resource usage and speed – congratulations you’re a programmer and have to make decisions about how your code will run.

What wasn’t mentioned was a third option – the foreach method

$i = 0

(1..1000).foreach({$i += $_})

$i

I don’t see the foreach (or where) method used very much but its always worth keeping at the back of your mind

I decided to run some tests

Measure-Command -Expression {

$i = 0

1..1000 | foreach {$i += $_}

$i

} | select TotalMilliseconds

Measure-Command -Expression {

$i = 0

foreach ($j in 1..1000) {$i += $j}

$i

} | select TotalMilliseconds

Measure-Command -Expression {

$i = 0

(1..1000).foreach({$i += $_})

$i

} | select TotalMilliseconds

I found that using the foreach loop was 2-4 times faster than using foreach-object on the pipeline.

The foreach method was about 2 times faster than foreach-object.

Testing your code for speed isn’t an exact science but some simple tests using measure-object can give you some interesting data.