Search code examples
powershellnullvoidio-redirection

What's the better (cleaner) way to ignore output in PowerShell?


Let's say you have a method or a cmdlet that returns something, but you don't want to use it and you don't want to output it. I found these two ways:

Add-Item > $null

[void]Add-Item

Add-Item | Out-Null

What do you use? Which is the better/cleaner approach? Why?


Solution

  • I just did some tests of the four options that I know about.

    Measure-Command {$(1..1000) | Out-Null}
    
    TotalMilliseconds : 76.211
    
    Measure-Command {[Void]$(1..1000)}
    
    TotalMilliseconds : 0.217
    
    Measure-Command {$(1..1000) > $null}
    
    TotalMilliseconds : 0.2478
    
    Measure-Command {$null = $(1..1000)}
    
    TotalMilliseconds : 0.2122
    
    ## Control, times vary from 0.21 to 0.24
    Measure-Command {$(1..1000)}
    
    TotalMilliseconds : 0.2141
    

    So I would suggest that you use anything but Out-Null due to overhead. The next important thing, to me, would be readability. I kind of like redirecting to $null and setting equal to $null myself. I use to prefer casting to [Void], but that may not be as understandable when glancing at code or for new users.

    I guess I slightly prefer redirecting output to $null.

    Do-Something > $null
    

    Edit

    After stej's comment again, I decided to do some more tests with pipelines to better isolate the overhead of trashing the output.

    Here are some tests with a simple 1000 object pipeline.

    ## Control Pipeline
    Measure-Command {$(1..1000) | ?{$_ -is [int]}}
    
    TotalMilliseconds : 119.3823
    
    ## Out-Null
    Measure-Command {$(1..1000) | ?{$_ -is [int]} | Out-Null}
    
    TotalMilliseconds : 190.2193
    
    ## Redirect to $null
    Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}
    
    TotalMilliseconds : 119.7923
    

    In this case, Out-Null has about a 60% overhead and > $null has about a 0.3% overhead.

    Addendum 2017-10-16: I originally overlooked another option with Out-Null, the use of the -inputObject parameter. Using this the overhead seems to disappear, however the syntax is different:

    Out-Null -inputObject ($(1..1000) | ?{$_ -is [int]})
    

    And now for some tests with a simple 100 object pipeline.

    ## Control Pipeline
    Measure-Command {$(1..100) | ?{$_ -is [int]}}
    
    TotalMilliseconds : 12.3566
    
    ## Out-Null
    Measure-Command {$(1..100) | ?{$_ -is [int]} | Out-Null}
    
    TotalMilliseconds : 19.7357
    
    ## Redirect to $null
    Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}
    
    TotalMilliseconds : 12.8527
    

    Here again Out-Null has about a 60% overhead. While > $null has an overhead of about 4%. The numbers here varied a bit from test to test (I ran each about 5 times and picked the middle ground). But I think it shows a clear reason to not use Out-Null.