Testing V4’s Where method and the pipeline

Continuing with the topic of the where() method and return types, I decided to to some bench testing.

I can get the same object type return from the where() collection method that I do from using the Where-Object comdlet by piping the collection to Set-Variable. But did I just give up the performance advantage using the method by sticking another pipeline into it?

Here’s my test setup:

$counter = 1..100

'Where-Object cmdlet'

  Measure-Command {

   foreach ($count in $counter)
    {$result = $counter | where {$_ -match '33'}}

  } | select TotalMilliseconds | fl 

'Where method, pipe to Set-Variable'
Measure-Command {

foreach ($count in $counter)
 {$counter.where({$_ -match '33'}) | Set-Variable result}

} | select TotalMilliseconds | fl 

'Where method, return collection'
Measure-Command {

foreach ($count in $counter)
{$result = $counter.Where({$_ -match '33'})}

} | select TotalMilliseconds | fl 

And the results:

Where-Object cmdlet
TotalMilliseconds : 704.2918

Where method, pipe to Set-Variable
TotalMilliseconds : 203.6046

Where method, return collection
TotalMilliseconds : 160.8534

It gave up some performance piping to Set-Variable, but not much.

The Where-Object pipeline had to handle every item in the array.
The where() pipeline only had to handle one.
Filter left.

2 responses to “Testing V4’s Where method and the pipeline

  1. That is pretty cool!
    Just for clarification (based on the last statement; which I might be misreading), the .Where() still handles every item in the array, the difference is that it loads everything into memory up front instead of streaming the objects through the pipeline to Where-Object. If you have the memory to support .Where() with a large collection, then it will be the best route to take.

    Using .Where()
    (1..10).Where({$_ -eq 2;write-verbose “$($_)” -Verbose})

    Using Where-Object
    (1..10) | Where-Object{$_ -eq 2;write-verbose “$($_)” -Verbose}

  2. That sounds about right. Being an array/collection method makes it implicit that you have to have it all in memory first. Using a pipeline and Set-Variable along with it should be a drop-in replacement for anywhere in an existing script you’re running a collection or array through Where-Object, without having to re-factor anything downstream that isn’t expecting a collection.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s