Skip to content

Make Span IndexOfAny a generic method with special case for byte #24445

@ahsonkhan

Description

@ahsonkhan

Similar to LastIndexOfAny (added here - dotnet/corefx#25848), change the IndexOfAny APIs to be generic. The premise is that there should be little performance degradation for the byte case when we make this change. This needs to be confirmed by comparing performance results before/after.

Change:

public static int IndexOfAny(this Span<byte> span, byte value0, byte value1) { throw null; }
public static int IndexOfAny(this Span<byte> span, byte value0, byte value1, byte value2) { throw null; }
public static int IndexOfAny(this Span<byte> span, ReadOnlySpan<byte> values) { throw null; }

public static int IndexOfAny(this ReadOnlySpan<byte> span, byte value0, byte value1) { throw null; }
public static int IndexOfAny(this ReadOnlySpan<byte> span, byte value0, byte value1, byte value2) { throw null; }
public static int IndexOfAny(this ReadOnlySpan<byte> span, ReadOnlySpan<byte> values) { throw null; }

To:

public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T> { throw null; }
public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T> { throw null; }
public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { throw null; }

public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T> { throw null; }
public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T> { throw null; }
public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T> { throw null; }

Example implementation change:

public static int IndexOfAny<T>(this Span<T> span, T value0, T value1)
    where T : IEquatable<T>
{
    if (typeof(T) == typeof(byte))
        return SpanHelpers.IndexOfAny(
            ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()),
            Unsafe.As<T, byte>(ref value0),
            Unsafe.As<T, byte>(ref value1),
            span.Length);
    return SpanHelpers.IndexOfAny(ref span.DangerousGetPinnableReference(), value0, value1, span.Length);
}

Then implement the following to SpanHelpers.T.cs

public static unsafe int IndexOfAny<T>(ref T searchSpace, T value0, T value1, int length)
            where T : IEquatable<T>

Should be relatively easy. cc @karelz

cc @KrzysztofCwalina, @GrabYourPitchforks

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions