-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ecb59aa
commit 94bed91
Showing
5 changed files
with
528 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#requires -version 3 | ||
<# | ||
.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 | ||
.EXAMPLE | ||
$array = 1..10000000 | ||
$hashtable = New-FastLookup $array | ||
Measure-Command { $array | Where-Object { $_ -eq 199999 } } | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 9 | ||
Milliseconds : 714 | ||
Measure-Command { Get-FastLookup -Value 199999 -Array $array -Table $hashtable } | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 0 | ||
Milliseconds : 65 | ||
[NOTE] Performance test on Windows 10 x64 (i5-6200U, 8GB RAM, SSD) | ||
#> | ||
|
||
$Functions = @( Get-ChildItem -Path $PSScriptRoot\*.ps1 -ErrorAction SilentlyContinue ) | ||
|
||
foreach ($Function in $Functions) | ||
{ | ||
Try | ||
{ | ||
. $Function.FullName | ||
} | ||
Catch | ||
{ | ||
Write-Error -Message "Failed to import function $($Function.FullName): $_" | ||
} | ||
} | ||
|
||
Export-ModuleMember -Alias 'FastLookup' | ||
Export-ModuleMember -Function $Functions.BaseName |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
function Get-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 | ||
.PARAMETER Array | ||
A mandatory parameter specifying the array used to create a 'FastLookup' (hashtable index) | ||
.PARAMETER Table | ||
A mandatory parameter specifying the 'FastLookup' created by New-FastLookup | ||
.PARAMETER Value | ||
A mandatory parameter specifying the search criteria (e.g. "Server458") | ||
.OUTPUTS | ||
The object(s) in the array that match the search | ||
.EXAMPLE | ||
PS> $array = 1..10000000 | ||
PS> $hashtable = New-FastLookup $array | ||
PS> Measure-Command { | ||
$array | Where-Object { $_ -eq 199999 } | ||
} | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 9 | ||
Milliseconds : 306 | ||
PS> Measure-Command { | ||
Get-FastLookup -Value 199999 -Array $array -Table $hashtable | ||
} | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 0 | ||
Milliseconds : 65 | ||
[NOTE] Performance test on Windows 10 x64 (i5-6200U, 8GB RAM, SSD) | ||
#> | ||
param( | ||
[Parameter(Mandatory=$true)] | ||
$Value, | ||
[Parameter(Mandatory=$true)] | ||
[Array]$Array, | ||
[Parameter(Mandatory=$true)] | ||
[Hashtable]$Table | ||
) | ||
|
||
Try | ||
{ | ||
# Lookup Value in hashtable | ||
$Index = $Table[$Value] | ||
|
||
# Find quantity of Index values | ||
$IndexQty = ($Index -split ",").Count | ||
|
||
# Find objects in Array based on Index | ||
# (if multiple, split into array) | ||
If ($IndexQty -eq 1){ $Array[$Index] } | ||
If ($IndexQty -ge 2){ $Array[$Index -split ","] } | ||
|
||
} | ||
Catch | ||
{ | ||
$null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
function New-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 | ||
.PARAMETER Array | ||
A mandatory parameter specifying input array used to create 'FastLookup' | ||
.PARAMETER Header | ||
An optional parameter specifying the header in the input array used to create 'FastLookup' | ||
.OUTPUTS | ||
A hashtable, listing the values in the array and their corresponding index | ||
.EXAMPLE | ||
PS> $array = 1..10000000 | ||
PS> $hashtable = New-FastLookup $array | ||
PS> Measure-Command { | ||
$array | Where-Object { $_ -eq 199999 } | ||
} | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 9 | ||
Milliseconds : 306 | ||
PS> Measure-Command { | ||
Get-FastLookup -Value 199999 -Array $array -Table $hashtable | ||
} | ||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 0 | ||
Milliseconds : 65 | ||
[NOTE] Performance test on Windows 10 x64 (i5-6200U, 8GB RAM, SSD) | ||
#> | ||
param( | ||
[Parameter(Mandatory=$true)] | ||
[array]$Array, | ||
$Header | ||
) | ||
|
||
# Identify headers in input array | ||
$Headers = $Array | Get-Member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name' | ||
|
||
# Define empty hashtable and index | ||
$HashTable = @{} | ||
$Index = 0 | ||
|
||
#1: Header specified | ||
#2: Header exists in array | ||
If (($Header -ne $null) -and ($Header -in $Headers)) | ||
{ | ||
# Redefine array with only data from specified Header | ||
$Array = $Array.$Header | ||
} | ||
|
||
#1: Header is specified | ||
#2: Header does NOT exist in array | ||
ElseIf (($Header -ne $null) -and ($Header -notin $Headers)) | ||
{ | ||
# Exit function with error | ||
Write-Error "Specified header ($Header) does not exist in input array." | ||
Break | ||
} | ||
|
||
#1: Header is NOT specified | ||
#2: Array contains multiple Headers | ||
ElseIf (($Header -eq $null) -and ($Headers.Count -gt 1)) | ||
{ | ||
# Exit function with error | ||
Write-Error "Input array requires the -Header parameter (multiple columns detected)." | ||
Break | ||
} | ||
|
||
# Loop through array | ||
foreach ($Item in $Array) | ||
{ | ||
# Add index of Item to hashtable | ||
# Name Value | ||
# ---- ----- | ||
# Server1 953 | ||
# Server2 1157 | ||
Try | ||
{ | ||
$HashTable.Add($Item,$Index) | ||
} | ||
|
||
# Duplicate key detected, add to existing value | ||
# Name Value | ||
# ---- ----- | ||
# Server1 953 | ||
# Server2 1157,3325 | ||
Catch | ||
{ | ||
$HashTable[$Item] = ($HashTable[$Item],$Index -join ",") | ||
} | ||
|
||
# Increment loop | ||
$Index++ | ||
} | ||
|
||
# Output results | ||
$HashTable | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,101 @@ | ||
# FastLookup | ||
|
||
PowerShell Module designed to optimize the speed of searching an array. | ||
|
||
## How It Works? | ||
|
||
The <b>FastLookup</b> module creates a hashtable, combining the Values in an array with the Index of the item in the array. Since the Name (or "Key") of the hashtable must be unique, each duplicate result is appended in the hashtable: | ||
|
||
PS> $array | ||
|
||
Laptop | ||
Workstation | ||
Laptop | ||
Router | ||
|
||
PS> $hashtable | ||
|
||
Name Value | ||
---- ----- | ||
Laptop 0,2 | ||
Workstation 1 | ||
Router 3 | ||
|
||
The larger the array, the more significant the performance increase from using FastLookup instead of Where-Object. Here are some speed differences when looking for an object in an array using Where-Object vs FastLookup (hashtable index) method: | ||
|
||
Array with 10000 rows (+6 columns): | ||
|
||
Where-Object: 145ms | ||
FastLookup: 25ms | ||
|
||
Array with 50000 rows (+6 columns): | ||
|
||
Where-Object: 973ms | ||
FastLookup: 53ms | ||
|
||
## Example (1 Column Array) | ||
|
||
PS> $array = 1..1000000 | ||
PS> $hashtable = New-FastLookup $array | ||
|
||
PS> Measure-Command { | ||
$array | Where-Object { $_ -eq 199999 } | ||
} | ||
|
||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 9 | ||
Milliseconds : 306 | ||
|
||
PS> Measure-Command { | ||
Get-FastLookup -Value 199999 -Array $array -Table $hashtable | ||
} | ||
|
||
Days : 0 | ||
Hours : 0 | ||
Minutes : 0 | ||
Seconds : 0 | ||
Milliseconds : 65 | ||
## Example (2+ Column Array) | ||
|
||
PS> $array | ||
|
||
DeviceName : Device38 | ||
Type : Security Camera | ||
IP : 10.10.128.1 | ||
VLAN : VLAN85 | ||
Location : Los Angeles | ||
Patch Window : Sunday | ||
|
||
DeviceName : Device68 | ||
Type : Server | ||
IP : 10.10.128.126 | ||
VLAN : VLAN15 | ||
Location : Chicago | ||
Patch Window : Sunday | ||
|
||
PS> $Hashtable = New-FastLookup -Array $Array -Header "Location" | ||
PS> Get-FastLookup -Value "Chicago" -Array $Array -Table $Hashtable | ||
|
||
DeviceName : Device68 | ||
Type : Server | ||
IP : 10.10.128.126 | ||
VLAN : VLAN15 | ||
Location : Chicago | ||
Patch Window : Sunday | ||
|
||
## Install | ||
|
||
Download [FastLookup.zip](https://github.com/milesgratz/FastLookup/releases/download/v1.0/FastLookup.zip) and extract the contents into `C:\Users\[User]\Documents\WindowsPowerShell\modules\Stretch` (you may have to create these directories if they don't exist.) | ||
|
||
## Releases | ||
* [v1.0](https://github.com/milesgratz/FastLookup/releases/download/v1.0/FastLookup.zip) | ||
|
||
## Contributors | ||
* [Miles Gratz](https://github.com/milesgratz) | ||
|
||
## Contact | ||
* Blog: [serveradventures.com](http://www.serveradventures.com) |
Oops, something went wrong.