diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs index 90c39104efbc8b..8c84415aaea093 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ValueListBuilder.cs @@ -13,11 +13,14 @@ internal ref partial struct ValueListBuilder private T[]? _arrayFromPool; private int _pos; - public ValueListBuilder(Span initialSpan) + public ValueListBuilder(Span scratchBuffer) { - _span = initialSpan; - _arrayFromPool = null; - _pos = 0; + _span = scratchBuffer!; + } + + public ValueListBuilder(int capacity) + { + Grow(capacity); } public int Length diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index 335ec2b55123e4..97b07d08bed620 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -5937,6 +5937,7 @@ public static Task WhenAll(IEnumerable tasks) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks); } + int? count = null; if (tasks is ICollection taskCollection) { if (tasks is Task[] taskArray) @@ -5949,19 +5950,23 @@ public static Task WhenAll(IEnumerable tasks) return WhenAll(CollectionsMarshal.AsSpan(taskList)); } - taskArray = new Task[taskCollection.Count]; - taskCollection.CopyTo(taskArray, 0); - return WhenAll((ReadOnlySpan)taskArray); + count = taskCollection.Count; } - else + + // Buffer the tasks into a temporary span. Small sets of tasks are common, + // so for <= 8 we stack allocate. + ValueListBuilder builder = count is > 8 ? + new ValueListBuilder(count.Value) : + new ValueListBuilder([null, null, null, null, null, null, null, null]); + foreach (Task task in tasks) { - var taskList = new List(); - foreach (Task task in tasks) - { - taskList.Add(task); - } - return WhenAll(CollectionsMarshal.AsSpan(taskList)); + builder.Append(task); } + + Task t = WhenAll(builder.AsSpan()); + + builder.Dispose(); + return t; } /// diff --git a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs index 00a37d7fa8c449..c7e9d49725e249 100644 --- a/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs +++ b/src/libraries/System.Text.RegularExpressions/src/System/Text/RegularExpressions/RegexReplacement.cs @@ -97,7 +97,7 @@ public RegexReplacement(string rep, RegexNode concat, Hashtable _caps) [InlineArray(4)] private struct FourStackStrings // used to do the equivalent of: Span strings = stackalloc string[4]; { - private string _item1; + private string? _item1; } ///