== 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` 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 [source,csharp,diff-id=1,diff-type=noncompliant] ---- string Interpolate(string value) => FormattableString.Invariant($"Value: {value}"); ---- [source,csharp,diff-id=2,diff-type=noncompliant] ---- string Interpolate(string value) => FormattableString.CurrentCulture($"Value: {value}"); ---- ==== Compliant solution [source,csharp,diff-id=1,diff-type=compliant] ---- string Interpolate(string value) => string.Create(CultureInfo.InvariantCulture, $"Value: {value}"); ---- [source,csharp,diff-id=2,diff-type=compliant] ---- string Interpolate(string value) => string.Create(CultureInfo.CurrentCulture, $"Value: {value}"); ---- == Resources === Documentation * https://learn.microsoft.com/en-us/dotnet/api/system.string.create?view=net-7.0[string.Create] * https://learn.microsoft.com/en-us/dotnet/api/system.formattablestring.invariant[FormattableString.Invariant] * https://learn.microsoft.com/en-us/dotnet/api/system.formattablestring.currentculture[FormattableString.CurrentCulture] === Articles & blog posts * https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated#compilation-of-interpolated-strings[Compilation of interpolated strings] === Benchmarks The results were generated by running the following snippet with https://github.com/dotnet/BenchmarkDotNet[BenchmarkDotNet]: [options="header"] |=== | Method | Runtime | Mean | StdDev | 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 |=== [source,csharp] ---- 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: [source] ---- 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 ----