Reputation: 403
I'm trying to select an Object-Output-Array from an Object-Array that has the Attribute Color to match with "blue", because the -match Operator has Performance Problems with matching the whole object-array to the Attribute (1-2 seconds on a large list)
Pseudocode:
$ObjectArray.Count => 999999
$ObjectArray.Color = "Red"
$ObjectArray[2342] = "Blue"
<#
$result = $ObjectArray -match "Blue" # Takes too Long
return $result
#>
# What I Need:
$result = Get-Object $Object from ObjectArray | where
($ObjectArray.color -match "Blue") # how to?
return $result
expected result:
$result
>>
ID : 2343
Color : Blue
$ObjectArray[0]
>>
ID : 1
Color : Red
Upvotes: 3
Views: 2898
Reputation: 25061
Assuming you only want the first match, this is what gave me the fastest search results:
$result = foreach ($obj in $objectarray) {
if ($obj.color -eq "blue") {
$obj
break
}
}
In my limited findings, -eq
appears to be a faster operator than -match
. Techniques that only return the first match can vary greatly depending on where the match exists within the array. A match at index 3 will return significantly quicker than a match at index 999999.
All tests below were done on an array with one million items.
Test Case 1: Using -match
Against the Whole Object
Measure-Command {
$result = $objectarray -match "blue"
$result
}
Days : 0
Hours : 0
Minutes : 2
Seconds : 3
Milliseconds : 799
Ticks : 1237994203
TotalDays : 0.00143286366087963
TotalHours : 0.0343887278611111
TotalMinutes : 2.06332367166667
TotalSeconds : 123.7994203
TotalMilliseconds : 123799.4203
Test Case 2: Using where()
Method with Default Mode and Operator -eq
Measure-Command {
$result = $objectarray.where{$_.color -eq "blue"}
}
Days : 0
Hours : 0
Minutes : 1
Seconds : 8
Milliseconds : 823
Ticks : 688235093
TotalDays : 0.000796568394675926
TotalHours : 0.0191176414722222
TotalMinutes : 1.14705848833333
TotalSeconds : 68.8235093
TotalMilliseconds : 68823.5093
Test Case 3: Using Where()
Method with First
Mode
Measure-Command {
$result = $objectarray.where({$_.color -eq "blue"},'First')
}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 12
Ticks : 128258
TotalDays : 1.48446759259259E-07
TotalHours : 3.56272222222222E-06
TotalMinutes : 0.000213763333333333
TotalSeconds : 0.0128258
TotalMilliseconds : 12.8258
Test Case 4: Using foreach
with break
Statement
measure-command {
$result = foreach ($obj in $objectarray) {
if ($obj.color -eq "blue") {
$obj
break
}
}
}
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 7
Ticks : 74482
TotalDays : 8.62060185185185E-08
TotalHours : 2.06894444444444E-06
TotalMinutes : 0.000124136666666667
TotalSeconds : 0.0074482
TotalMilliseconds : 7.4482
Test Case 5: Using where()
Method with -match
operator
Measure-Command {
$result = $objectarray.where{$_.color -match "^blue"}
}
Days : 0
Hours : 0
Minutes : 1
Seconds : 25
Milliseconds : 58
Ticks : 850588447
TotalDays : 0.000984477369212963
TotalHours : 0.0236274568611111
TotalMinutes : 1.41764741166667
TotalSeconds : 85.0588447
TotalMilliseconds : 85058.8447
Test Case 6: Piping to Where-Object
Measure-Command {
$result = $objectarray | where-object {$_.color -eq "blue"}
}
Days : 0
Hours : 0
Minutes : 2
Seconds : 50
Milliseconds : 478
Ticks : 1704782030
TotalDays : 0.00197312734953704
TotalHours : 0.0473550563888889
TotalMinutes : 2.84130338333333
TotalSeconds : 170.478203
TotalMilliseconds : 170478.203
Upvotes: 2