I'm looking for a method to find an element in array which is fast and can be done by short code. I tried the following 4 codes; Code 1 is straightforward and fastest. Code 2 and Code 3 are compact but slower. Code 4 is slowest because the array is entirely iterated.
From the perspective of performance Code 1 is the best but looks ugly. Is there any short code like Code 2 or Code 3 and fast like Code 1?
Code
$list = 0..99
# Code 1
Write-Host "Code 1:" (Measure-Command {
$list | % {
$target = $_
$found = $null
foreach ($elem in $list) {
if ($elem -eq $target) {
$found = $target
break
}
}
}
}).TotalSeconds
# Code 2
Write-Host "Code 2:" (Measure-Command {
$list | % {
$target = $_
$found = [Array]::Find($list, [Predicate[Int]]{ $args[0] -eq $target })
}
}).TotalSeconds
# Code 3
Write-Host "Code 3:" (Measure-Command {
$list | % {
$target = $_
$found = [System.Linq.Enumerable]::First($list, [Func[object,bool]]{ param($x) $x -eq $target })
}
}).TotalSeconds
# Code 4
Write-Host "Code 4:" (Measure-Command {
$list | % {
$target = $_
$found = $null
$founds = @($list | ? { $_ -eq $target })
if ($founds.Count -gt 0) {
$found = $founds[0]
}
}
}).TotalSeconds
Output
Code 1: 0.0595818
Code 2: 0.1851123
Code 3: 0.1719588
Code 4: 0.3455028
REPL
FYI
In JavaScript I always use Code B than Code A as it's shorter and performs better. This is what I want to do in PowerShell.
Code
const list = Array.from(Array(100)).map((_, i) => i);
// Code A
console.time("Code A");
list.forEach(target => {
let found = undefined;
for (const elem of list) {
if (elem === target) {
found = elem;
break;
}
}
});
console.timeEnd("Code A");
// Code 2
console.time("Code B");
list.forEach(target => {
const found = list.find(elem => elem === target);
});
console.timeEnd("Code B");
Output
Code A: 0.539ms
Code B: 0.215ms