MemoryExtensions.Replace(Span<T>, T, T) implemented (#76337)
authorGünther Foidl <gue@korporal.at>
Fri, 11 Nov 2022 20:50:56 +0000 (21:50 +0100)
committerGitHub <noreply@github.com>
Fri, 11 Nov 2022 20:50:56 +0000 (15:50 -0500)
commit005e2802d5ccce2e1755aa7d46cf03f2271ab203
treeec769e4359e392efefbc5dc534d3fbe3b0202000
parent68b828489c1c219f3514a95803f99ba450260d0f
MemoryExtensions.Replace(Span<T>, T, T) implemented (#76337)

* Defined API

* Tests

* Scalar implementation

* Use EqualityComparer<T>.Default instead

* Delegation to SpanHelpers.Replace

* ReplaceValueType implemented

* Use ushort instead of short, as it doesn't sign-extend for broadcast and in the scalar loop

* Forward string.Replace(char, char) to SpanHelpers.ReplaceValueType

* Process remainder vectorized only when not done already and with max width available

* Split into inlineable scalar path and non-inlineable vectorized path

* Replaced open coded loops with Replace

* Don't use EqualityComparer<T>.Default

Cf. https://github.com/dotnet/runtime/pull/76337#discussion_r982886319

* Remove guards for remainder

Cf. https://github.com/dotnet/runtime/pull/76337#discussion_r983448480

* Don't split method into scalar and vectorized and don't force inlining of scalar-part

* Fixed assert

ReplaceValueType is called from string.Replace(char, char) so the Debug.Assert was on wrong position, as at entry to method non accelerated platforms are allowed to call it.

* Better handling of remainder from the vectorized loop(s)

Intentionally leave one iteration off, as the remaining elements are done vectorized anyway. This eliminates the less probable case (cf. https://github.com/dotnet/runtime/pull/76337#discussion_r983448480) that the last vector is done twice.

* PR feedback
src/libraries/Common/src/System/IO/Archiving.Utils.Unix.cs
src/libraries/Common/src/System/IO/Archiving.Utils.Windows.cs
src/libraries/System.Memory/ref/System.Memory.cs
src/libraries/System.Memory/tests/Span/Replace.T.cs [new file with mode: 0644]
src/libraries/System.Memory/tests/System.Memory.Tests.csproj
src/libraries/System.Private.CoreLib/src/System/MemoryExtensions.cs
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.T.cs
src/libraries/System.Private.CoreLib/src/System/String.Manipulation.cs
src/libraries/System.Private.CoreLib/src/System/Text/StringBuilder.cs
src/libraries/System.Private.Uri/src/System/Uri.cs