Stop Using the Pipeline in PowerShell
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 Count | Using Pipeline | Without Pipeline |
---|---|---|
200,000 | 6.7s | 1.8s |
400,000 | 12.7s | 3.5s |
800,000 | 26.4s | 8.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