Stop Using the Pipeline in PowerShell

Share on:

Last week I Fred Bainbridge and Ryan Ephgrave's MMSMOA session where they showed us that we shouldn't be using the pipeline anymore.  Before beginning the session, I was as confused as you might be about why.  The guys did a great job explaining it and I'm going to show you why in the same manner they showed me.

Let's start with a really basic array of numbers:

1$numbers = 0..200000

Now, you want to do something with these numbers, right?  Let's say we're going to write them out to a file:

1$numbers | Out-File $env:temp\test1.txt -Append

Easy enough, and if I throw a Measure-Command around it (example at the bottom of this post), this takes 4.44s to execute.

Now, let's try this again, but without using the pipe to pass the input-object:

1Out-File -FilePath $env:TEMP\test2.txt -InputObject $numbers -Append

Measuring this command, I'm completing in just 1.434!  That's slightly more than 3x faster. This is consistent, every time, within a few milliseconds, and it doesn't matter if I put one test on top or the other.  And it goes up exponentially - it's not linear movement.

If I double the number to 400,000 and rerun the tests, the pipeline code runs in 9.0s while not using it runs in 2.8s.  If I double that again to 800,000 we're looking at 18.69s for the pipeline method, while the non-pipeline method runs in just 5.81s.  You can see here that the larger our set gets, the more of a performance hit we take using the pipeline.

Over multiple runs, the numbers change by milliseconds but there is always a measurable difference.  Here is just one example of a run on my laptop:

Array CountUsing PipelineWithout Pipeline
200,0006.7s1.8s
400,00012.7s3.5s
800,00026.4s8.2s

Thanks to the awesome presenters at MMSMAO for this awesome new knowledge!

Completed test script:

 1$numbers = 0..200000
 2$moreNumbers = 0..400000
 3$evenMoreNumbers = 0..800000
 4
 5$(Measure-Command {
 6     $numbers | Out-File $env:temp\test1.txt -Append
 7}).TotalSeconds
 8
 9$(Measure-Command {
10     Out-File -FilePath $env:TEMP\test2.txt -InputObject $numbers -Append
11}).TotalSeconds
12
13Remove-Item $env:temp\test1.txt
14Remove-Item $env:temp\test2.txt
15
16$(Measure-Command {
17     $moreNumbers | Out-File $env:temp\test1.txt -Append
18}).TotalSeconds
19
20$(Measure-Command {
21     Out-File -FilePath $env:TEMP\test2.txt -InputObject $moreNumbers -Append
22}).TotalSeconds
23
24Remove-Item $env:temp\test1.txt
25Remove-Item $env:temp\test2.txt
26
27$(Measure-Command {
28     $evenMoreNumbers | Out-File $env:temp\test1.txt -Append
29}).TotalSeconds
30
31$(Measure-Command {
32     Out-File -FilePath $env:TEMP\test2.txt -InputObject $evenMoreNumbers -Append
33}).TotalSeconds
34
35Remove-Item $env:temp\test1.txt
36Remove-Item $env:temp\test2.txt


No comments