Test-FastLookup.ps1
function Test-FastLookup { <# .SYNOPSIS Lookup a value in an array faster than Where-Object .DESCRIPTION Improve the speed of looking up a value in an array by creating a hashtable index. Good for looking up results in very large arrays or CSV files (e.g Import-Csv) .NOTES Version: 1.0 Author: Miles Gratz Creation Date: April 10, 2017 Purpose/Change: Initial script development .OUTPUTS 1. Creates a sample array 2. Compares speed of Where-Object vs Get-FastLookup (using Measure-Command) .EXAMPLE PS > Test-FastLookup Creating 'speedtest' array, total quantity: 50000 Example object: DeviceName : Device38 Type : Security Camera IP : 10.10.128.1 VLAN : VLAN85 Location : Los Angeles Patch Window : Sunday Creating hashtable: $Hashtable = New-FastLookup -Array $Array -Header "Location" -------------------------------------------------------------------------------- Measuring speed of Where-Object lookup: $Array | Where-Object { $_.Location -eq "Chicago" } Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 971 Number of results: 16468 First result: DeviceName : Device1 Type : Network Switch IP : 10.10.128.47 VLAN : VLAN90 Location : Chicago Patch Window : Sunday -------------------------------------------------------------------------------- Measuring speed of Get-FastLookup lookup: Get-FastLookup -Value "Chicago" -Array $array -Table $hashtable Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 71 Number of results: 16468 First result: DeviceName : Device1 Type : Network Switch IP : 10.10.128.47 VLAN : VLAN90 Location : Chicago Patch Window : Sunday [NOTE] Performance test on Windows 10 x64 (i5-6200U, 8GB RAM, SSD) #> param( # Default sample size of 50K [int]$Quantity = 50000 ) # Define empty array and index $Array = @() $Index = 0 # Create array based on quantity Write-Output "Creating 'speedtest' array, total quantity: $Quantity" while ($Index -lt $Quantity) { # Calculate percentage $PercentageIndex = $Percentage $Percentage = [math]::Round((($Index / $Quantity)*100)) # Announce percentage If ($Percentage -gt $PercentageIndex) { Write-Output "Creating 'speedtest' array ($Percentage%)" } # Example template $DeviceNumber = 1..100 | Get-Random $Type = Get-Random 'Laptop','Workstation','Network Switch','Wireless Access Point','Security Camera','Server' $IP = "10.10.128." + (Get-Random (1..254)) $VLAN = "VLAN" + (Get-Random (1..100)) $Location = Get-Random 'Chicago','New York','Los Angeles' $PatchWindow = Get-Random 'Sunday','Saturday' # Create custom object to add to array $Object = New-Object PSCustomObject $Object | Add-Member -MemberType NoteProperty -name "DeviceName" -Value "Device$DeviceNumber" $Object | Add-Member -MemberType NoteProperty -name "Type" -Value "$Type" $Object | Add-Member -MemberType NoteProperty -name "IP" -Value "$IP" $Object | Add-Member -MemberType NoteProperty -name "VLAN" -Value "$VLAN" $Object | Add-Member -MemberType NoteProperty -name "Location" -Value "$Location" $Object | Add-Member -MemberType NoteProperty -name "Patch Window" -Value "$PatchWindow" # Add object to array $Array += $Object # Increment loop $Index++ } # Example object Write-Output "" Write-Output "Example object:" Write-Output $Array[0] # Creating New-FastLookup hashtable Write-Output "" Write-Output "Creating hashtable: " Write-Output "" Write-Output ('$Hashtable = New-FastLookup -Array $Array -Header "Location"') $Hashtable = New-FastLookup -Array $Array -Header "Location" # Measuring speed of Where-Object lookup Write-Output "" Write-Output ('-'*80) Write-Output 'Measuring speed of Where-Object lookup:' Write-Output "" Write-Output ('$Array | Where-Object { $_.Location -eq "Chicago" }') $MeasureWhereObject = Measure-Command { $WhereObjectResults = $Array | Where-Object { $_.Location -eq "Chicago" } } | Select Days,Hours,Minutes,Seconds,Milliseconds Write-Output $MeasureWhereObject Write-Output "" Write-Output "Number of results: $($WhereObjectResults.Count)" Write-Output "First result:" Write-Output "" Write-Output $WhereObjectResults[0] # Measuring speed of Get-FastLookup Write-Output ('-'*80) Write-Output 'Measuring speed of Get-FastLookup lookup:' Write-Output "" Write-Output ('Get-FastLookup -Value "Chicago" -Array $array -Table $hashtable') $MeasureFastLookup = Measure-Command { $FastLookupResults = Get-FastLookup -Value "Chicago" -Array $Array -Table $Hashtable } | Select Days,Hours,Minutes,Seconds,Milliseconds Write-Output "" Write-Output $MeasureFastLookup Write-Output "" Write-Output "Number of results: $($FastLookupResults.Count)" Write-Output "First result:" Write-Output "" Write-Output $FastLookupResults[0] } |