Do not concatenate strings inside loops
TypeName |
DoNotConcatenateStringsInsideLoops |
CheckId |
CA1818 |
Category |
Microsoft.Performance |
Breaking Change |
NonBreaking |
Cause
A method iteratively builds a string inside an iteration statement, such as a for or while loop, using the System.String.Concat method or using the addition (+ or &) or addition assignment (+=) operators.
Rule Description
A System.String object is immutable. When two strings are concatenated, a new String object is created. Iterative string concatenation creates multiple strings that are un-referenced and must be garbage collected. For better performance, use the System.Text.StringBuilder class.
StringBuilder maintains a mutable character buffer, which allows string concatenation and other changes to occur without the overhead of object creation and garbage collection. The initial capacity of the StringBuilder is an important performance consideration. When the capacity is no longer sufficient to hold the string, the original buffer is discarded and another buffer is created with twice the capacity of the original.
How to Fix Violations
To fix a violation of this rule, use an instance of the StringBuilder class to build the string inside the iteration statement. After the string is built, use the System.Text.StringBuilder.ToString method to access the string.
When to Exclude Warnings
Exclude a warning from this rule if the temporary strings are used inside the iteration statement. In this case, StringBuilder does not offer a performance gain because its ToString method also creates a new String object on each iteration.
Example
The following example shows four violations of this rule, one of which should be excluded, and a method, Loop5
, which satisfies the rule using a StringBuilder.
Imports System
Imports System.Globalization
Imports System.Text
Namespace PerformanceLibrary
Class MakeString
Shared currentCulture As CultureInfo = CultureInfo.CurrentCulture
Shared Sub Main()
' Loops 1 through 4 violate this rule.
Loop1()
Loop2()
Loop3()
Loop4()
Loop5()
End Sub
Shared Sub Loop1()
Dim digits As String = String.Empty
For I As Integer = 0 To 9
digits = String.Concat(digits, I.ToString(currentCulture))
Next I
Console.WriteLine(digits)
End Sub
' This method violates the rule but
' the violation should be excluded.
Shared Sub Loop2()
Dim digits As String = String.Empty
For I As Integer = 0 To 9
digits = String.Concat(digits, I.ToString(currentCulture))
Console.WriteLine(digits)
Next I
End Sub
Shared Sub Loop3()
Dim digits As String = String.Empty
For I As Integer = 0 To 9
digits = digits & I.ToString(currentCulture)
Next I
Console.WriteLine(digits)
End Sub
Shared Sub Loop4()
Dim digits As String = String.Empty
For I As Integer = 0 To 9
digits += i.ToString(currentCulture)
Next I
Console.WriteLine(digits)
End Sub
' This method does not cause a violation of the rule.
Shared Sub Loop5()
Dim digits As New StringBuilder()
For I As Integer = 0 To 9
digits.Append(I.ToString(currentCulture))
Next I
Console.WriteLine(digits)
End Sub
End Class
End Namespace
using System;
using System.Globalization;
using System.Text;
namespace PerformanceLibrary
{
class MakeString
{
static CultureInfo currentCulture = CultureInfo.CurrentCulture;
static void Main()
{
// Loops 1 through 4 violate this rule.
Loop1();
Loop2();
Loop3();
Loop4();
Loop5();
}
static void Loop1()
{
string digits = string.Empty;
for(int i = 0; i < 10; i++)
{
digits = String.Concat(digits, i.ToString(currentCulture));
}
Console.WriteLine(digits);
}
// This method violates the rule but
// the violation should be excluded.
static void Loop2()
{
string digits = string.Empty;
for(int i = 0; i < 10; i++)
{
digits = String.Concat(digits, i.ToString(currentCulture));
Console.WriteLine(digits);
}
}
static void Loop3()
{
string digits = string.Empty;
for(int i = 0; i < 10; i++)
{
digits = digits + i.ToString(currentCulture);
}
Console.WriteLine(digits);
}
static void Loop4()
{
string digits = string.Empty;
for(int i = 0; i < 10; i++)
{
digits += i.ToString(currentCulture);
}
Console.WriteLine(digits);
}
// This method does not cause a violation of the rule.
static void Loop5()
{
StringBuilder digits = new StringBuilder();
for(int i = 0; i < 10; i++)
{
digits.Append(i.ToString(currentCulture));
}
Console.WriteLine(digits.ToString());
}
}
}
Related Rules
Avoid unnecessary string creation
Do not call properties that clone values in loops
Test for empty strings using string length
See Also
Reference
+ Operator (C# Reference)
Concatenation Operators (Visual Basic)