Add/use internal String.Concat overloads for spans by stephentoub · Pull Request #21766 · dotnet/coreclr (original) (raw)
In the common case where it need to replace a non-empty extension with a non-empty extension, it currently incurs a substring without the original extension prior to then concatenating with the new extension. This PR avoids that.
(As the Path
implementation is in corelib, this uses string.FastAllocateString
and then formats into it with a span; if we wanted to avoid that, string.Create
could also be used. That could also be addressed with new String.Concat
overloads that accept ReadOnlySpan<char>
s.)
Benchmark:
[Benchmark] public string ChangeExtensionReplace() => Path.ChangeExtension(@"c:\this\is\a\path\hello.txt", ".dat"); [Benchmark] public string ChangeExtensionRemove() => Path.ChangeExtension(@"c:\this\is\a\path\hello.txt", null);
Before:
Method | Mean | Error | StdDev | Gen 0 | Allocated |
----------------------- |---------:|----------:|----------:|-------:|----------:|
ChangeExtensionReplace | 41.39 ns | 1.4013 ns | 2.7985 ns | 0.0363 | 152 B |
ChangeExtensionRemove | 18.57 ns | 0.2763 ns | 0.2449 ns | 0.0172 | 72 B |
After:
Method | Mean | Error | StdDev | Gen 0 | Allocated |
----------------------- |---------:|----------:|----------:|-------:|----------:|
ChangeExtensionReplace | 18.66 ns | 0.1989 ns | 0.1764 ns | 0.0191 | 80 B |
ChangeExtensionRemove | 18.81 ns | 0.2678 ns | 0.2505 ns | 0.0172 | 72 B |
cc: @JeremyKuhne, @jkotas