111 lines
2.9 KiB
Plaintext
111 lines
2.9 KiB
Plaintext
== Why is this an issue?
|
|
|
|
Concatenating multiple string literals or strings using the `+` operator creates a new string object for each concatenation. This can lead to a large number of intermediate string objects and can be inefficient. The `StringBuilder` class is more efficient than string concatenation, especially when the operator is repeated over and over as in loops.
|
|
|
|
== How to fix it
|
|
|
|
Replace string concatenation with `StringBuilder`.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,csharp,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
string str = "";
|
|
for (int i = 0; i < arrayOfStrings.Length ; ++i)
|
|
{
|
|
str = str + arrayOfStrings[i];
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,csharp,diff-id=1,diff-type=compliant]
|
|
----
|
|
StringBuilder bld = new StringBuilder();
|
|
for (int i = 0; i < arrayOfStrings.Length; ++i)
|
|
{
|
|
bld.Append(arrayOfStrings[i]);
|
|
}
|
|
string str = bld.ToString();
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder[StringBuilder Class]
|
|
|
|
=== Benchmarks
|
|
|
|
[options="header"]
|
|
|===
|
|
| Method | Runtime | Mean | Standard Deviation | Allocated
|
|
| StringConcatenation | .NET 9.0 | 50,530.75 us | 2,699.189 us | 586280.70 KB
|
|
| StringBuilder | .NET 9.0 | 82.31 us | 3.387 us | 243.79 KB
|
|
| StringConcatenation | .NET Framework 4.8.1 | 37,453.72 us | 1,543.051 us | 586450.38 KB
|
|
| StringBuilder | .NET Framework 4.8.1 | 178.32 us | 6.148 us | 244.15 KB
|
|
|===
|
|
|
|
==== Glossary
|
|
|
|
* https://en.wikipedia.org/wiki/Arithmetic_mean[Mean]
|
|
* https://en.wikipedia.org/wiki/Standard_deviation[Standard Deviation]
|
|
|
|
The results were generated by running the following snippet with https://github.com/dotnet/BenchmarkDotNet[BenchmarkDotNet]:
|
|
|
|
[source,csharp]
|
|
----
|
|
[Params(10_000)]
|
|
public int Iterations;
|
|
|
|
[Benchmark]
|
|
public void StringConcatenation()
|
|
{
|
|
string str = "";
|
|
for (int i = 0; i < Iterations; i++)
|
|
{
|
|
str = str + "append";
|
|
}
|
|
}
|
|
|
|
[Benchmark]
|
|
public void StringBuilder()
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
for (int i = 0; i < Iterations; i++)
|
|
{
|
|
builder.Append("append");
|
|
}
|
|
_ = builder.ToString();
|
|
}
|
|
----
|
|
|
|
Hardware Configuration:
|
|
|
|
[source]
|
|
----
|
|
BenchmarkDotNet v0.14.0, Windows 10 (10.0.19045.5247/22H2/2022Update)
|
|
12th Gen Intel Core i7-12800H, 1 CPU, 20 logical and 14 physical cores
|
|
[Host] : .NET Framework 4.8.1 (4.8.9282.0), X64 RyuJIT VectorSize=256
|
|
.NET 9.0 : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2
|
|
.NET Framework 4.8.1 : .NET Framework 4.8.1 (4.8.9282.0), X64 RyuJIT VectorSize=256
|
|
----
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
include::../message.adoc[]
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::../comments-and-links.adoc[]
|
|
|
|
endif::env-github,rspecator-view[]
|