[NoBrainer] Performance Considerations regarding using Guid.ToString vs Guid.Guid in PowerShell

While doing some performance optimisations on one our loader scripts I came across an issue of converting a System.Guid or [[Guid]] in PowerShell to a string representation. In C# I was always (and still am) using ToString() and never saw anything like a Guid property. However, for some reason in PowerShell I tended to use the Guid property (instead of ToString()). I really never thought about this before, but a Sunday like today really gave me a good excuse to have a closer look at it.

First thing to mention was, that Guid is really a script property instead of a native property as you can see in the last line (hence it is not visible in C#):

PS > $guid = [Guid]::NewGuid()
PS > $guid | gm

   TypeName: System.Guid

Name        MemberType     Definition
----        ----------     ----------
CompareTo   Method         int CompareTo(System.Object value), int CompareTo( ...
Equals      Method         bool Equals(System.Object o), bool Equals(guid g), ...
GetHashCode Method         int GetHashCode()
GetType     Method         type GetType()
ToByteArray Method         byte[] ToByteArray()
ToString    Method         string ToString(), string ToString(string format), ...
Guid        ScriptProperty System.Object Guid {get=$this.ToString();}

Now it made me curious about the performance impact this might have when processing large data sets. So with Measure-Command I gave it a quick try.

Guid Conversion via Guid ScriptProperty

As you can see from the result (inside a virtual machine on my fours years old notebook) one single operation (including the loop overhead) took 0.02699 ms:

PS > $cMax = 5000000; 
PS > $m = Measure-Command -Expression { 
  for($c = 0; $c -lt $cMax; $c++) 
  { 
    $null = [guid]::NewGuid().Guid; 
  }
};

PS > $m | Select TotalMilliseconds | ft -AutoSize;
TotalMilliseconds
-----------------
      134996.4048

PS > $m.TotalMilliseconds / $cMax;
0.02699928096

Guid Conversion via ToString Method

Of course I expected the native ToString() method to be faster than the scripted one, but by a factor of more than 15: 0.0046 per single operation (again including loop overhead)! So in the case of our loader script it made a difference to replace all [Guid]::NewGuid().Guid occurences with [Guid]::NewGuid().ToString().

PS > $cMax = 5000000; 
PS > $m = Measure-Command -Expression { 
  for($c = 0; $c -lt $cMax; $c++) 
  { 
    $null = [guid]::NewGuid().ToString(); 
  }
};

PS > $m | Select TotalMilliseconds | ft -AutoSize;
TotalMilliseconds
-----------------
       23011.7742

PS > $m.TotalMilliseconds / $cMax;
0.00460235484

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: