-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: {Last}IndexOf{AnyExcept}Range #76106
Comments
Tagging subscribers to this area: @dotnet/area-system-memory Issue DetailsBackground and motivationIn looking over various code bases, it's relatively common to want to search for things in or out of a particular range. For example, check whether the input contains anything outside of the range [0x20, 0x7e]: runtime/src/libraries/Common/src/System/Net/HttpValidationHelpers.cs Lines 26 to 33 in fa5dcda
Or find the next index that's not an ASCII digit: runtime/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs Lines 188 to 194 in 239ff86
Or find the index of the first ASCII digit: runtime/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs Lines 32 to 39 in 239ff86
Or determine whether the input contains anything outside of the range of a byte: runtime/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs Lines 68 to 79 in 239ff86
Or find the index of the first upper-case ASCII letter: runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs Lines 431 to 439 in 239ff86
Or find the first index of a value that's at least some integer: runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/EastAsianLunisolarCalendar.cs Lines 387 to 393 in 239ff86
Etc. Today we don't provide an IndexOfXx method that makes it easy to search for such ranges. And even if/when we provide a more general and vectorized IndexOfAny that supports more than 5 characters (#68328), it's likely that such a method will be both harder to use (e.g. an initialization method and the actual method) and less efficient (because it's more complicated) than if we just have an IndexOfRange that lets you search for a simple range of values. API Proposalnamespace System
public static class MemoryExtensions
{
public static int IndexOfRange<T>(thisReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int IndexOfRange<T>(thisSpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int IndexOfAnyExceptRange<T>(thisReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int IndexOfAnyExceptRange<T>(thisSpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int LastIndexOfRange<T>(thisReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int LastIndexOfRange<T>(thisSpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int LastIndexOfAnyExceptRange<T>(thisReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
public static int LastIndexOfAnyExceptRange<T>(thisSpan<T> span, T lowInclusive, T highInclusive) where T : INumber<T>;
}
API Usageinternal static bool IsOnlyDigits(string str, int offset, int count) =>
str.AsSpan(offset, count).IndexOfAnyExceptRange('0', '9') < 0; Alternative DesignsNo response RisksNo response
|
Based on past experience of vectorizing similar methods, there'll potentially be a penalty for the shortest inputs. Is it possible that some of the above examples would be faster remaining in their current form? (Eg the IP address example) |
Possible, sure. There may be an extra few nanoseconds if the input is really small, basically the overhead of a method call and a length check. |
namespace System;
public partial class MemoryExtensions
{
public static int IndexOfAnyInRange<T>(this ReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int IndexOfAnyInRange<T>(this Span<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int IndexOfAnyExceptInRange<T>(this ReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int IndexOfAnyExceptInRange<T>(this Span<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int LastIndexOfAnyInRange<T>(this ReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int LastIndexOfAnyInRange<T>(this Span<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int LastIndexOfAnyExceptInRange<T>(this ReadOnlySpan<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
public static int LastIndexOfAnyExceptInRange<T>(this Span<T> span, T lowInclusive, T highInclusive) where T : IComparable<T>;
} |
Background and motivation
In looking over various code bases, it's relatively common to want to search for things in or out of a particular range.
For example, check whether the input contains anything outside of the range [0x20, 0x7e]:
runtime/src/libraries/Common/src/System/Net/HttpValidationHelpers.cs
Lines 26 to 33 in fa5dcda
Or find the next index that's not an ASCII digit:
runtime/src/libraries/Common/src/System/Net/IPv6AddressHelper.Common.cs
Lines 188 to 194 in 239ff86
Or find the index of the first ASCII digit:
runtime/src/libraries/System.Private.CoreLib/src/System/Environment.OSVersion.Unix.cs
Lines 32 to 39 in 239ff86
Or determine whether the input contains anything outside of the range of a byte:
runtime/src/libraries/System.Net.Http/src/System/Net/Http/Headers/UriHeaderParser.cs
Lines 68 to 79 in 239ff86
Or find the index of the first upper-case ASCII letter:
runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/TextInfo.cs
Lines 431 to 439 in 239ff86
Or find the first index of a value that's at least some integer:
runtime/src/libraries/System.Private.CoreLib/src/System/Globalization/EastAsianLunisolarCalendar.cs
Lines 387 to 393 in 239ff86
Etc. Today we don't provide an IndexOfXx method that makes it easy to search for such ranges. And even if/when we provide a more general and vectorized IndexOfAny that supports more than 5 characters (#68328), it's likely that such a method will be both harder to use (e.g. an initialization method and the actual method) and less efficient (because it's more complicated) than if we just have an IndexOfRange that lets you search for a simple range of values.
API Proposal
INumber<T>
implementations. That's the same set of types as what we already vectorize in other operations, but as we're able to open up that set further (e.g. [API Proposal]: IBitwiseEquatable<T> #75642), it likely won't extend to these.?
. My intent is the implementation will validate that the range values are non-null.API Usage
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: