String concatenation performance boosting - is this too much ado about nothing?
Concatenating strings is a common operation in programming, but did you know that there are different methods you can use to do it? In this post, we will explore four popular methods for string concatenation in PowerShell and compare their performance.
The Methods
The four methods we will focus on are:
- += operator
- -join operator
- [string]::Concat() method
- StringBuilder class with the .append() method
To test these methods, we will generate a 9-character long string by randomly selecting characters between ASCII codes 65 and 90, and then concatenate this string 10,000 times. We will time each method and compare their performance. Here's the code we'll use to generate the strings:
$((0..8).foreach({
[char]$(Get-Random -Minimum 65 -Maximum 90)
}) -join "")
The Test
#classic += method
$Superlongstring = [string]::empty
$StopWatch = New-Object System.Diagnostics.Stopwatch
$StopWatch.Start()
(0..10000).foreach({
$Superlongstring +=$((0..8).foreach({
[char]$(Get-Random -Minimum 65 -Maximum 90)
}) -join "")
})
$StopWatch.Stop()
$TestList.add([PSCustomObject]@{
Method = "+= method"
TimeElapsed = $StopWatch.Elapsed
TimeElapsedMS = $StopWatch.ElapsedMilliseconds
})
#join string method
$Superlongstring = [string]::empty
$StopWatch = New-Object System.Diagnostics.Stopwatch
$StopWatch.Start()
(0..10000).foreach({
$Superlongstring = -join($Superlongstring,$((0..8).foreach({
[char]$(Get-Random -Minimum 65 -Maximum 90)
})))
})
$StopWatch.Stop()
$TestList.add([PSCustomObject]@{
Method = "-join method"
TimeElapsed = $StopWatch.Elapsed
TimeElapsedMS = $StopWatch.ElapsedMilliseconds
})
#string concat method
$Superlongstring = [string]::empty
$StopWatch = New-Object System.Diagnostics.Stopwatch
$StopWatch.Start()
(0..10000).foreach({
$Superlongstring = [string]::Concat($Superlongstring,$((0..8).foreach({
[char]$(Get-Random -Minimum 65 -Maximum 90)
}) -join ""))
})
$StopWatch.Stop()
$TestList.add([PSCustomObject]@{
Method = "string concat method"
TimeElapsed = $StopWatch.Elapsed
TimeElapsedMS = $StopWatch.ElapsedMilliseconds
})
#stringbuilder class method
$Superlongstring = [System.Text.StringBuilder]::new()
$StopWatch = New-Object System.Diagnostics.Stopwatch
$StopWatch.Start()
(0..10000).foreach({
$Superlongstring.append($((0..8).foreach({
[char]$(Get-Random -Minimum 65 -Maximum 90)
}) -join "")) | Out-Null
})
$Superlongstring = $Superlongstring.tostring()
$StopWatch.Stop()
$TestList.add([PSCustomObject]@{
Method = "stringbuilder class method"
TimeElapsed = $StopWatch.Elapsed
TimeElapsedMS = $StopWatch.ElapsedMilliseconds
})
The Results
After running the test, we get the following results:
Method | TimeElapsed | TimeElapsedMS |
---|---|---|
+= method | 00:00:02.9537727 | 2953 |
-join method | 00:00:04.5625753 | 4562 |
string concat method | 00:00:05.0997880 | 5099 |
stringbuilder class method | 00:00:02.4714697 | 2471 |
The Conclusion
The second fastest method was the += operator, but the fastest was the StringBuilder class with the .append() method. It's worth noting that with the StringBuilder method, we needed to convert the object back to a string using the .ToString() method, but even with this additional step, it was still faster than the other methods.
If you have any thoughts or feedback on this topic, feel free to share them with me on Twitter at Christian Ritter.
All tests were conducted using PowerShell 7.x.
Best regards,
Christian.