Skip to content

Commit

Permalink
NET-934 Modify S1643: Add benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastien-marichal committed Jan 6, 2025
1 parent 8db2c95 commit 4056a8e
Showing 1 changed file with 78 additions and 7 deletions.
85 changes: 78 additions & 7 deletions rules/S1643/csharp/rule.adoc
Original file line number Diff line number Diff line change
@@ -1,30 +1,101 @@
== Why is this an issue?

``++StringBuilder++`` is more efficient than string concatenation, especially when the operator is repeated over and over as in loops.
Concatenating string literals or strings in a loop 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.

=== Noncompliant code example
== How to fix it

[source,csharp]
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)
for (int i = 0; i < arrayOfStrings.Length ; ++i)
{
str = str + arrayOfStrings[i];
}
----

=== Compliant solution
==== Compliant solution

[source,csharp]
[source,csharp,diff-id=1,diff-type=compliant]
----
StringBuilder bld = new StringBuilder();
for (int i = 0; i < arrayOfStrings.Length; ++i)
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 8.0 | 17,523.51 us | 316.022 us | 370543.43 KB
| StringBuilder | .NET 8.0 | 33.39 us | 0.637 us | 155.69 KB
| StringConcatenation | .NET 9.0 | 17,808.63 us | 485.294 us | 370543.42 KB
| StringBuilder | .NET 9.0 | 30.51 us | 0.646 us | 155.69 KB
| StringConcatenation | .NET Framework 4.6.2 | 18,544.31 us | 201.981 us | 371066.30 KB
| StringBuilder | .NET Framework 4.6.2 | 388.64 us | 4.279 us | 539.58 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 + i;
}
}
[Benchmark]
public void StringBuilder()
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < Iterations; i++)
{
builder.Append(i);
}
_ = 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 8.0 : .NET 8.0.11 (8.0.1124.51707), X64 RyuJIT AVX2
.NET 9.0 : .NET 9.0.0 (9.0.24.52809), X64 RyuJIT AVX2
.NET Framework 4.6.2 : .NET Framework 4.8.1 (4.8.9282.0), X64 RyuJIT VectorSize=256
----

ifdef::env-github,rspecator-view[]

'''
Expand Down

0 comments on commit 4056a8e

Please sign in to comment.