PowerShell Performance Series Part 3 (.NET method call not always faster as PowerShell shortcut)
Continuing on from Karl's post's :
Fast New PSCustomObject.
generating a "PropertyBag" aka PScustomObject in C#
Getting serious about performance in PowerShell.
and mine
PowerShell Performance Series Part 2 (Get-PerformanceHistory.ps1)
PowerShell Performance Series Part 1 (Warming Up)
I did go on from Karl's last post Fast New PSCustomObject. where he used a HashTable to add the Properties and questioned the performance, so I converted his sample to a CTP2 Add-Type example and tested generating the Hashtable with an added method to ObjGen to create a HashTable, so to get a nice way in code to create the HashTable that is still performant.
I got some nice results again :
- Creating HashTables with @{} does not preserve order (know issue) see output below
- creating a HashTable from objGen and adding properties to it slows down considerable
- Using the PowerShell Shortcut, just assigning the values to non existing properties (very convenient ) , is actually faster as using the Add method and brings back speed to comparable speed with Karl's method :
Especialy 3 item did surprise and pleasure me

As you can see from the output above just assigning the not existing properties in the HashTable is faster as using the Add method, so this method looks better in Code AND is faster so a win-win situation
Lesson learned, convenient shortcuts are not always slower
My testing code :
$class = @"
public static class ObjGen
{
public static System.Collections.Hashtable GetHashTable (){return new System.Collections.Hashtable(); }
public static System.Management.Automation.PSObject GetPSObject( System.Collections.Hashtable noteproperties )
{
System.Management.Automation.PSObject obj = new System.Management.Automation.PSObject();
if (noteproperties != null)
{
foreach(System.Collections.DictionaryEntry item in noteproperties)
{
obj.Properties.Add(new System.Management.Automation.PSNoteProperty((string)item.Key,item.Value));
}
}
return obj;
}
}
"@
add-type $class
. c:\powershell\Get-PerformanceHistory.ps1
1..50000 |% {[ObjGen]::GetPSObject($null)}
1..50000 |% {new-object PSObject}
.{
[ObjGen]::GetPSObject(@{name="karl";age=31;now = [datetime]::Now}) | out-host
$p = [ObjGen]::GetHashTable()
$p.Add("name","karl")
$p.add("age",31)
$p.add("now",[datetime]::Now)
[ObjGen]::GetPSObject($p) | out-host
$p = [ObjGen]::GetHashTable()
$p.name = "karl"
$p.age = 31
$p.now = [datetime]::Now
[ObjGen]::GetPSObject($p) | out-host
}
1..50000 |% {[void][ObjGen]::GetPSObject(@{name="karl";age=31;now = [datetime]::Now})}
1..50000 |% {
$p = [ObjGen]::GetHashTable()
$p.Add("name","karl")
$p.add("age",31)
$p.add("now",[datetime]::Now)
[void][ObjGen]::GetPSObject($p)
}
1..50000 |% {
$p = [ObjGen]::GetHashTable()
$p.name = "karl"
$p.age = 31
$p.now = [datetime]::Now
[void][ObjGen]::GetPSObject($p)
}
Get-PerformanceHistory 6
# h | select com*,{[datetime]$_.EndExecutionTime - [datetime]$_.StartExecutionTime}
Also testing showed the HashTable method of Objgen is realy not needed as the @{} construct for hashtables PowerShell is also faster as this method.
4.45300 0.00009 1..50000 |% {$p = [ObjGen]::GetHashTable()}
4.11800 0.00008 1..50000 |% {$p = @{}}
but using New-Object for this is a bad plan :
16.32000 0.00033 1..50000 |% {$p = new-object hashtable}
* Update * PowerShell V1 users can test the "hashTable adding difference" by running these 2 lines and comparing them
1..50000 |% {$p = @{};$p.Add("name","karl"); $p.add("age",31); $p.add("now",[datetime]::Now)}
1..50000 |% {$p = @{};$p.name = "karl";$p.age = 31;$p.now = [datetime]::Now}
Enjoy,
Greetings /\/\o\/\/