Question:
I am writing a PowerShell script where many integers have to be converted to strings. I am using the ToString
method to do this, as in:
1 2 3 |
$i = 5 $i.ToString() |
Unfortunately, this seems to be very slow (I omitted the execution policy warning):
1 2 3 4 5 |
PS I:\ADCC\Scripting Performance> .\int_to_str.ps1 6.747561 PS I:\ADCC\Scripting Performance> .\int_to_str.py 0.37243021680382793 |
I am using PowerShell 2 and Python 3.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
PS I:\ADCC\Scripting Performance> $PSVersionTable Name Value ---- ----- CLRVersion 2.0.50727.5485 BuildVersion 6.1.7601.17514 PSVersion 2.0 WSManStackVersion 2.0 PSCompatibleVersions {1.0, 2.0} SerializationVersion 1.1.0.1 PSRemotingProtocolVersion 2.1 PS I:\ADCC\Scripting Performance> python --version Python 3.6.1 |
This is the contents of int_to_str.ps1
:
1 2 3 4 5 6 |
(Measure-Command { ForEach($i in 1..1000000){ $i.ToString() } }).TotalSeconds |
This is the contents of int_to_str.py
:
1 2 3 4 5 6 7 |
#!/usr/bin/env python3 import time start = time.perf_counter() for i in range(1, 1000000): str(i) print(time.perf_counter() - start) |
As you can see, both scripts convert integers from 1 to 1,000,000 to strings. However, while PowerShell takes 6.75 seconds, Python only takes 0.37 seconds, making Python 18 times faster. In the actual PowerShell script that I am writing, it takes about three hours to convert all of the integers to strings, so an 18-fold speed improvement would be welcome.
Is there a faster way to convert an int
to a string
in PowerShell 2?
Answer:
To answer your question, even in .NET (which is what you’re using with PowerShell), here is a great article on the int->string conversion you care about: http://cc.davelozinski.com/c-sharp/fastest-way-to-convert-an-int-to-string.
As far as byte array conversions from AD, here is a test I did and with explicit casting to a [string[]]
, I nearly always saw gains over using .tostring(). The gains ranged from 50% to equivalent but it was consistently faster:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$s = [adsisearcher]'(&(objectCategory=user)(samaccountname=mysam))' $r = @($s.FindAll()) (Measure-Command { foreach ($b in $r[0].Properties.userpassword[0]) { $b.tostring() } }).TotalSeconds (Measure-Command { [string[]]$r[0].Properties.userpassword[0] }).TotalSeconds |