-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Improve pref of Array.IndexOf()
for certain T
.
#24293
Conversation
Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in dotnet#20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`.
Unsafe.As<T, long>(ref value), | ||
count); | ||
return (result >= 0 ? startIndex : 0) + result; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder - is it possible to replace it all with return new Span<T>(array, startIndex, count).IndexOf(value);
to re-use that MemoryExtensions code with IsBitwiseEquatable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MemoryExtensions.IndexOf<T>(Span<T>, T)
requires that T
implement IEquatable<T>
, and while we know that all types for which IsBitwiseEquatable<T>()
currently returns true
satisfy that requirement, there is no way to tell that to the compiler.
Do you have any numbers that show how much this change improved the performance? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! The change looks good me once it is supported by numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Echoing Jan's comments: LGTM, but would like to see numbers.
I tested using the same logic as the For example: [Benchmark]
public int ArrayIndexOf()
{
int result = 0;
var values = _values;
var found = _found;
for (int i = 0; i < found.Length; i++)
result ^= Array.IndexOf(values, found[i]);
return result;
} BenchmarkDotNet=v0.11.5, OS=Windows 10.0.17134.706 (1803/April2018Update/Redstone4)
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
Frequency=3609369 Hz, Resolution=277.0567 ns, Timer=TSC
.NET Core SDK=3.0.100-preview5-011281
[Host] : .NET Core 3.0.0-preview5-27613-06 (CoreCLR 4.6.27613.71, CoreFX 4.700.19.21214), 64bit RyuJIT
Job-JLWIJH : .NET Core ? (CoreCLR 4.6.27620.0, CoreFX 4.700.19.21911), 64bit RyuJIT
Job-OBNZOS : .NET Core ? (CoreCLR 4.6.27620.0, CoreFX 4.700.19.21911), 64bit RyuJIT
IterationTime=250.0000 ms MaxIterationCount=20 MinIterationCount=15
WarmupCount=1
|
The CI failures are unrelated. I wouldn't block this merge waiting for CI to go green. |
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in #20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in #20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
Thanks @dschinde for your contribution! :) |
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in #20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in mono#20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in #20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in #20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Signed-off-by: dotnet-bot <[email protected]>
) Applies changes to `Array.IndexOf()` and `Array.LastIndexOf()` similar to the changes made in dotnet/coreclr#20855, so that types other than `byte` and `char` can use use the fast vectorized path. Also allows 32-bit and 64-bit types for which `RuntimeHelpers.IsBitwiseEquatable<T>()` returns `true` to use the faster implementation of `IndexOf` and `LastIndexOf` from `MemoryExtensions`. Commit migrated from dotnet/coreclr@2551753
Applies changes to
Array.IndexOf()
andArray.LastIndexOf()
similarto the changes made in #20855, so that types other than
byte
andchar
can use use the fast vectorized path.Also allows 32-bit and 64-bit types for which
RuntimeHelpers.IsBitwiseEquatable<T>()
returnstrue
to use thefaster implementation of
IndexOf
andLastIndexOf
fromMemoryExtensions
.