<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://powershell.com/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Dreaming in PowerShell : $null</title><link>http://powershell.com/cs/blogs/tobias/archive/tags/_2400_null/default.aspx</link><description>Tags: $null</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 (Build: 30929.2835)</generator><item><title>Don't Waste Speed - How To Activate The PowerShell Turbo Mode</title><link>http://powershell.com/cs/blogs/tobias/archive/2012/05/01/don-t-waste-speed-how-to-activate-the-powershell-turbo-mode.aspx</link><pubDate>Tue, 01 May 2012 20:35:00 GMT</pubDate><guid isPermaLink="false">f421715f-7aba-45f0-8a8d-44de5318a3a7:16311</guid><dc:creator>Tobias</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://powershell.com/cs/blogs/tobias/rsscomments.aspx?PostID=16311</wfw:commentRss><comments>http://powershell.com/cs/blogs/tobias/archive/2012/05/01/don-t-waste-speed-how-to-activate-the-powershell-turbo-mode.aspx#comments</comments><description>&lt;p&gt;This afternoon, my buddy Alexandar (and fellow PowerShell MVP from Serbia) reviewed another batch of PowerTips when he stumbled across some lines of code that looked a bit unintuitive to him and asked to rephrase them. Sometimes there is more than one way to Rome. There is nothing bad about having choices. Today &lt;strong&gt;I&amp;#39;d like to show how to pick the fastest way&lt;/strong&gt; to Rome - and how you can speed up your PowerShell code tremendously by knowing about some easy design rules.&lt;/p&gt;
&lt;h3&gt;Understanding&amp;nbsp;The PowerShell Pipeline&lt;/h3&gt;
&lt;p&gt;The PowerShell pipeline is a great feature but&amp;nbsp;many users&amp;nbsp;aren&amp;#39;t aware that the &lt;strong&gt;pipeline actually is a throttling mechanism&lt;/strong&gt; designed to &lt;strong&gt;minimize memory consumption&lt;/strong&gt;. When you read in a large file, for example, by reading this file line-by-line and processing each line over the pipeline, only one line at a time needs to be stored in memory. That&amp;#39;s why PowerShell can easily read and process huge log files.&lt;/p&gt;
&lt;p&gt;The backside is that &lt;strong&gt;speed is fueled by memory and CPU&lt;/strong&gt;. The memory throttling done by the PowerShell &lt;strong&gt;pipeline takes away memory&lt;/strong&gt; and &lt;strong&gt;reduces speed&lt;/strong&gt;. And the results can be significant. Have a look:&lt;/p&gt;
&lt;p&gt;PS&amp;gt; 1..100 | Get-Random&lt;br /&gt;66&lt;br /&gt;PS&amp;gt; 1..10000 | Get-Random&lt;br /&gt;9746&lt;br /&gt;PS&amp;gt; 1..1000000 | Get-Random&lt;br /&gt;509967&lt;/p&gt;
&lt;p&gt;All of these lines generate a range of numbers and then pick one random number from it. When you try this for yourself, you&amp;#39;ll notice that the first two commands run almost instantaneously. The third line however takes forever. The overhead produced by the PowerShell pipeline accumulates with each element that needs to travel across it. So in the last command, one million numbers need to travel one by one to &lt;strong&gt;Get-Random&lt;/strong&gt;, and that takes a lot of time.&lt;/p&gt;
&lt;p&gt;In many scenarios, the great &lt;strong&gt;memory-saving aspect&lt;/strong&gt; of the PowerShell pipeline is not important at all. In our current example, it definitely does not matter. So here you can speed up things easily by avoiding the pipeline and passing the data directly to the parameter that would else receive it over the pipeline:&lt;/p&gt;
&lt;div class="pscode"&gt;PS&amp;gt; &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Random&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-InputObject&lt;/span&gt;&lt;/span&gt; (1..1000000)&lt;br /&gt;770786&lt;/div&gt;
&lt;p&gt;Notice how the very same operation takes only a fraction of a second instead of many seconds.&lt;/p&gt;
&lt;h3&gt;Every Day Scenarios To Save Time&lt;/h3&gt;
&lt;p&gt;There are tons of every day scenarios that you can speed up this way. Let&amp;#39;s start with a very common one: &lt;strong&gt;discarding data&lt;/strong&gt;. When you do not need data, you have the choice of piping it to &lt;strong&gt;Out-Nu&lt;/strong&gt;ll or assigning it to the special variable &lt;strong&gt;$null&lt;/strong&gt;. Guess which way is faster? Test for yourself:&lt;/p&gt;
&lt;div class="pscode"&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {1..100000 | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Out-Null&lt;/span&gt;&lt;/span&gt; }).&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;TotalMilliseconds&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;1114,3006 &lt;span style="color:#008000;"&gt;&lt;span class="comment"&gt;#!!!!!!!!!!! Over 1 f...ing second !!!!!!!!!!)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$null&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; 1..100000 }).&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;TotalMilliseconds&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;29,3192&lt;br /&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {1..100000 &amp;gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$null&lt;/span&gt;&lt;/span&gt; }).&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;TotalMilliseconds&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;38,1542&lt;br /&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {[&lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt;&lt;/span&gt;](1..100000) }).&lt;span style="color:#8b4513;"&gt;&lt;span class="method"&gt;TotalMilliseconds&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;28,2378&lt;/div&gt;
&lt;p&gt;All of these lines do the same: they dump data. The first approach uses the pipeline and takes &lt;strong&gt;over a second&lt;/strong&gt;! Assigning the data to &lt;strong&gt;$null&lt;/strong&gt; just takes lightning &lt;strong&gt;fast 30ms&lt;/strong&gt;. Holy Moly.&amp;nbsp;Of course the performance difference depends on how much data you need to dump. Often, it is much less than 100000 elements, so the performance gain becomes less impressive. However, just imagine this statement as part of a &lt;strong&gt;loop&lt;/strong&gt; that runs a number of times. Each time the loop runs, the &lt;strong&gt;peformance penalty sums up&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Here is yet another common scenario: a loop. Some people use the pipeline to create loops:&lt;/p&gt;
&lt;div class="pscode"&gt;PS&amp;gt; 1..100000 | &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;ForEach-Object&lt;/span&gt;&lt;/span&gt; { &lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;quot;looping for the $_. time&amp;quot;&lt;/span&gt;&lt;/span&gt; }&lt;/div&gt;
&lt;p&gt;On my machine, it takes approximately &lt;strong&gt;7 seconds&lt;/strong&gt; (on yours it can be much faster, the point is just the relative comparison).&lt;/p&gt;
&lt;p&gt;The same loop can also be written without a pipeline, like this:&lt;/p&gt;
&lt;div class="pscode"&gt;PS&amp;gt; for (&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$x&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt;1; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$x&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;-le&lt;/span&gt;&lt;/span&gt; 100000; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$x&lt;/span&gt;&lt;/span&gt;&lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;++&lt;/span&gt;&lt;/span&gt;) {&lt;br /&gt;&lt;span style="color:#800000;"&gt;&lt;span class="string"&gt;&amp;quot;looping for the $x. time&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;}&lt;/div&gt;
&lt;p&gt;This one takes just 0,5 seconds. That&amp;#39;s a heck of a noticable speed increase.&lt;/p&gt;
&lt;h3&gt;The Pipeline Is EveryWhere&lt;/h3&gt;
&lt;p&gt;Sometimes, it is not so apparent that PowerShell is using the Pipeline when it really does. Here is some typical code:&lt;/p&gt;
&lt;p&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Content&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;windowsupdate.log&lt;/span&gt;&lt;/span&gt; | &lt;br /&gt;&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Foreach-Object&lt;/span&gt;&lt;/span&gt; { &lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;quot;reading line $_&amp;quot;&lt;/span&gt;&lt;/span&gt; }&lt;/p&gt;
&lt;p&gt;}).&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;TotalSeconds&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;1.2655871&lt;/p&gt;
&lt;p&gt;Compare this to the version that avoids the pipeline:&lt;/p&gt;
&lt;div class="pscode"&gt;PS&amp;gt; (&lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Measure-Command&lt;/span&gt;&lt;/span&gt; {&lt;br /&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="pscode"&gt;&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$all&lt;/span&gt;&lt;/span&gt; &lt;span class="op"&gt;&lt;span style="color:#ff0000;"&gt;=&lt;/span&gt;&lt;/span&gt; &lt;span class="verbnoun"&gt;&lt;span style="color:#5f9ea0;"&gt;Get-Content&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$env:windir&lt;/span&gt;&lt;/span&gt;\&lt;span class="namespace"&gt;&lt;span style="color:#8b4513;"&gt;windowsupdate.log&lt;/span&gt;&lt;/span&gt; &lt;span class="modifier"&gt;&lt;span style="color:#5f9ea0;"&gt;-ReadCount&lt;/span&gt;&lt;/span&gt; 0&lt;br /&gt;&lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;Foreach&lt;/span&gt;&lt;/span&gt;(&lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$line&lt;/span&gt;&lt;/span&gt; &lt;span class="keyword"&gt;&lt;span style="color:#0000ff;"&gt;in&lt;/span&gt;&lt;/span&gt; &lt;span class="var"&gt;&lt;span style="color:#800080;"&gt;$all&lt;/span&gt;&lt;/span&gt;) { &lt;span class="string"&gt;&lt;span style="color:#800000;"&gt;&amp;quot;reading line $line&amp;quot;&lt;/span&gt;&lt;/span&gt; }&lt;br /&gt;&lt;/div&gt;
&lt;div class="pscode"&gt;}).&lt;span class="method"&gt;&lt;span style="color:#8b4513;"&gt;TotalSeconds&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;0.0848887&lt;/p&gt;
&lt;p&gt;Again, &lt;strong&gt;more than 14 times faster&lt;/strong&gt;. The thing to watch out here is to use &lt;strong&gt;Get-Content&lt;/strong&gt; with the parameter&lt;strong&gt; -ReadCount 0&lt;/strong&gt;. Without it, Get-Content by default is optimized for the pipeline and emits each line as a single object, causing again a lot of work for the pipeline.&lt;/p&gt;
&lt;h3&gt;Conclusions&lt;/h3&gt;
&lt;p&gt;The PowerShell &lt;strong&gt;pipeline is a great feature&lt;/strong&gt;! In the last example, thanks to the pipeline, just one line of a file needed to be stored in memory. The faster version without the pipeline, in contrast, needed to hold the entire text file in memory (variable &lt;strong&gt;$all&lt;/strong&gt;). So this article is not about avoiding the pipeline. It is about &lt;strong&gt;using the PowerShell resources wisely&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You have seen that there is a &lt;strong&gt;tradeoff: speed or small memory footprint&lt;/strong&gt;. Use the pipeline if you must conserve memory. Avoid the pipeline if you need speed. And take a look again at some of the initial examples: there are a lot of standard code scenarios where conserving memory really isn&amp;#39;t an issue. So by not using the Pipeline here, you can improve performance easily.&lt;/p&gt;
&lt;p&gt;Stay tuned...!&lt;/p&gt;
&lt;p&gt;Tobias&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Microsoft MVP PowerShell Germany&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;P.S.&lt;br /&gt;If you live in Germany or other parts of Europe and your company would like to set up a truly great PowerShell training, just contact me! I regularly train mid- to large-size companies. Trainings are always a blast with tons of real-world-examples and solutions. Here&amp;#39;s how to get in touch with me: &lt;a href="mailto:tobias.weltner@scriptinternals.de"&gt;&lt;span style="color:#3366cc;"&gt;tobias.weltner@scriptinternals.de&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://powershell.com/cs/aggbug.aspx?PostID=16311" width="1" height="1"&gt;</description><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Get-Content/default.aspx">Get-Content</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Get-Random/default.aspx">Get-Random</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/_2400_null/default.aspx">$null</category><category domain="http://powershell.com/cs/blogs/tobias/archive/tags/Out-Null/default.aspx">Out-Null</category></item></channel></rss>