You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Avoid defensive copy in String.Concat(string[]) (#4559)
* Avoid defensive copy in String.Concat(string[])
Today the String.Concat(params string[]) implementation makes a defensive copy of the input string[] in order to avoid issues where another thread mutates the array concurrently with the concatenation. Such a situation is possible but exceedingly rare, so we can redo the implementation to make it cheaper when there isn't concurrent mutation and more expensive when there is, rather than always having it be more expensive.
This commit changes string.Concat to optimistically assume there won't be such concurrent mutation. It avoids allocating the defensive string[] array copy, and instead just proceeds to allocate a string of the right length and copy the input strings into it. If along the way it discovers that something has changed such that the string lengths no longer add up to exactly what was precomputed, then it falls back to the original implementation.
Example microbenchmark:
```C#
using System;
using System.Diagnostics;
public class Program
{
public static void Main()
{
string result;
string[] inputs = new[] { "abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz" };
var sw = new Stopwatch();
while (true)
{
int gen0 = GC.CollectionCount(0);
sw.Restart();
for (int i = 0; i < 20000000; i++) result = string.Concat(inputs);
sw.Stop();
Console.WriteLine($"{GC.CollectionCount(0) - gen0}: {sw.Elapsed.TotalSeconds}");
}
}
}
```
Before the change:
```
> corerun test.exe
1525: 2.0733829
1526: 2.0599474
1526: 2.0717786
1526: 2.0318797
^C
```
After the change:
```
> corerun test.exe
763: 1.4700695
762: 1.446919
763: 1.4581139
763: 1.4568889
^C
```
0 commit comments