0

Speeding up PowerShell Arrays

 3 years ago
source link: https://virtuallysober.com/2020/08/06/speeding-up-powershell-arrays/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Speeding up PowerShell Arrays

Published August 6, 2020 by Joshua Stenhouse
0
light trails on highway at night

I do a lot of work with REST APIs and reporting in PowerShell which means I’m constantly working with arrays. This allows me to calculate, combine and store the results from querying multiple API endpoints from multiple sources. My preferred method for creating arrays has always been this:

$Array = @()
# Doing a ForEach, then adding to array
$Data = New-Object PSObject
$Data | Add-Member -MemberType NoteProperty -Name "Field1" -Value $DataHere
$Data | Add-Member -MemberType NoteProperty -Name "Field2" -Value $DataHere
$Data | Add-Member -MemberType NoteProperty -Name "Field3" -Value $DataHere
$Array += $Data

This allows you to control the order of the columns and gives me an easy way to see what data is going where, especially useful when you have lots of columns to store. I’ve been using this method for years, and it has served me well.

But, I was recently doing some work on a large dataset, roughly 30,000 objects to process and enter in an array, and I noticed it slowing down significantly as it went along to the point of it becoming a big problem.

So I started investigating any way I could make it faster and it turns out there is a more efficient way to create and add to the array, giving you a significant speed increase, and it only requires 2 small changes. Specifically the first and last lines:

$Array = [System.Collections.ArrayList]@()
# Doing a ForEach, then adding to array
$Data = New-Object PSObject
$Data | Add-Member -MemberType NoteProperty -Name "Field1" -Value $DataHere
$Data | Add-Member -MemberType NoteProperty -Name "Field2" -Value $DataHere
$Data | Add-Member -MemberType NoteProperty -Name "Field3" -Value $DataHere
$Array.Add($Data) | Out-Null

How does this speed it up? Using += actually recreates the entire array on each add. No problem on a few thousand rows, but at scale it really starts to impact processing time. The ArrayList method just adds the new row like you would expect.

Let’s now run them side by side so you can do your own benchmarking:

# Old way
$OldArray = @()
$Numbers = 1..30000
$Count = 0
$Start = Get-Date
ForEach ($Number in $Numbers)
{
# Adding to array
$Data = New-Object PSObject
$Data | Add-Member -MemberType NoteProperty -Name "Number" -Value $Number
$Data | Add-Member -MemberType NoteProperty -Name "Field1" -Value "Data1"
$Data | Add-Member -MemberType NoteProperty -Name "Field2" -Value "Data2"
$Data | Add-Member -MemberType NoteProperty -Name "Field3" -Value "Data3"
$OldArray += $Data
# Incrementing count
$count ++
# User output
"Old-Count: $count"
}
$End = Get-Date 
$Timespan = New-TimeSpan -Start $Start -End $End
$OldWayTimeTaken = $Timespan | Select -ExpandProperty TotalMinutes
# New way
$NewArray = [System.Collections.ArrayList]@()
$Numbers = 1..30000
$Count = 0
$Start = Get-Date
ForEach ($Number in $Numbers)
{
# Adding to array
$Data = New-Object PSObject
$Data | Add-Member -MemberType NoteProperty -Name "Number" -Value $Number
$Data | Add-Member -MemberType NoteProperty -Name "Field1" -Value "Data1"
$Data | Add-Member -MemberType NoteProperty -Name "Field2" -Value "Data2"
$Data | Add-Member -MemberType NoteProperty -Name "Field3" -Value "Data3"
$NewArray.Add($Data) | Out-Null
# Incrementing count
$count ++
# User output
"New-Count: $count"
}
$End = Get-Date 
$Timespan = New-TimeSpan -Start $Start -End $End
$NewWayTimeTaken = $Timespan | Select -ExpandProperty TotalMinutes
# Result
"--------------------------------
NewwayMinutes:$NewWayTimeTaken
OldWayMinutes: $OldWayTimeTaken
--------------------------------"

On my Surface Pro X at 10,000 rows I don’t see much improvement. But at 30,000 I see it run 2x faster. Huge!

Suffice to say I now have a new method for creating and storing arrays and I am going to go back and update previous scripts where this would be beneficial. Proof that we can all continuously improve! I hope you found it useful too. Happy scripting,

Joshua

Like this:

Loading...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK