org.sonar.plugins.csharp.S6618.html Maven / Gradle / Ivy
Why is this an issue?
In order to produce a formatted string, both string.Create
and either FormattableString.Invariant
or
FormattableString.CurrentCulture
can be used. However, string.Create
rents array buffers from
ArrayPool<char>
making it more performant, as well as preventing unnecessary allocations and future stress on the Garbage
Collector.
This applies to .NET versions after .NET 6, when these string.Create
overloads were introduced.
What is the potential impact?
We measured a significant improvement both in execution time and memory allocation. For more details see the Benchmarks
section from
the More info
tab.
How to fix it
Replace calls to FormattableString.CurrentCulture
or FormattableString.Invariant
with calls to
string.Create(CultureInfo.CurrentCulture, …)
or string.Create(CultureInfo.InvariantCulture, …)
respectively.
Code examples
Noncompliant code example
string Interpolate(string value) =>
FormattableString.Invariant($"Value: {value}");
string Interpolate(string value) =>
FormattableString.CurrentCulture($"Value: {value}");
Compliant solution
string Interpolate(string value) =>
string.Create(CultureInfo.InvariantCulture, $"Value: {value}");
string Interpolate(string value) =>
string.Create(CultureInfo.CurrentCulture, $"Value: {value}");
Resources
Documentation
Articles & blog posts
Benchmarks
The results were generated by running the following snippet with BenchmarkDotNet:
Method
Runtime
Mean
Standard Deviation
Allocated
StringCreate
.NET 7.0
152.5 ms
3.09 ms
83.92 MB
FormattableString
.NET 7.0
191.8 ms
6.92 ms
198.36 MB
Glossary
The results were generated by running the following snippet with BenchmarkDotNet:
int Value = 42;
DateTime Now = DateTime.UtcNow;
[Params(1_000_000)]
public int N;
[Benchmark]
public void StringCreate()
{
for (int i = 0; i < N; i++)
{
_ = string.Create(CultureInfo.InvariantCulture, $"{Now}: Value is {Value}");
}
}
[Benchmark]
public void FormattableStringInvariant()
{
for (int i = 0; i < N; i++)
{
_ = FormattableString.Invariant($"{Now}: Value is {Value}");
}
}
Hardware configuration:
BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2728/22H2/2022Update)
11th Gen Intel Core i7-11850H 2.50GHz, 1 CPU, 16 logical and 8 physical cores
.NET SDK=7.0.203
[Host] : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2
.NET 7.0 : .NET 7.0.5 (7.0.523.17405), X64 RyuJIT AVX2