-
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]: Add ImmutableArray.Contains overload that accepts an IEqualityComparer<T> #66758
Comments
Tagging subscribers to this area: @dotnet/area-system-collections Issue DetailsBackground and motivationI recently had a significant inner-loop performance regression when I added an optional Apparently there is no such overload, so it the call was directed from: public readonly struct ImmutableArray<T>
{
// ...
public bool Contains(T item)
// ...
} to Linq's: public static class Enumerable
{`
// ...
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource>? comparer);
// ...
} This caused a significant amount of boxing to API Proposalpublic readonly struct ImmutableArray<T>
{
// ...
public bool Contains(T item, IEqualityComparer<T>? equalityComparer)
{
var self = this;
return self.IndexOf(item, 0, self.Length, equalityComparer) >= 0;
}
// ...
} API UsageImmutableArray<string> items = ImmutableArray.Create("abc", "DEF");
Assert.True(items.Contains("Abc", StringComparer.InvariantCultureIgnoreCase));
Assert.True(items.Contains("Def", StringComparer.InvariantCultureIgnoreCase)); Alternative DesignsNo response RisksThis has a really low risk of breaking something. It should increase the overall performance when
|
Given that it is fairly common for concrete collections to fall back to slower LINQ methods, I'm not necessarily convinced that it's sufficient justification to add another overload in |
Yes, the required functionality is already present in ImmutableArray.IndexOf, so this can easily be expressed as an extension method. However that argument would also apply to the single-argument Contains method already present. |
Is it not an option to add this overload to the set of LINQ extensions specialized for |
I think that's the best option. |
SGTM, given there's precedent. @ChrML could you update your API proposal to use that namespace? |
Tagging subscribers to this area: @dotnet/area-system-linq Issue DetailsBackground and motivationI recently had a significant inner-loop performance regression when I added an optional Apparently there is no such overload, so it the call was directed from: public readonly struct ImmutableArray<T>
{
// ...
public bool Contains(T item)
// ...
} to Linq's: public static class Enumerable
{`
// ...
public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource>? comparer);
// ...
} This caused a significant amount of boxing to API Proposalpublic readonly struct ImmutableArray<T>
{
// ...
public bool Contains(T item, IEqualityComparer<T>? equalityComparer)
{
var self = this;
return self.IndexOf(item, 0, self.Length, equalityComparer) >= 0;
}
// ...
} API UsageImmutableArray<string> items = ImmutableArray.Create("abc", "DEF");
Assert.True(items.Contains("Abc", StringComparer.InvariantCultureIgnoreCase));
Assert.True(items.Contains("Def", StringComparer.InvariantCultureIgnoreCase)); Alternative DesignsNo response RisksThis has a really low risk of breaking something. It should increase the overall performance when
|
If OP isn't going to update, then I'll place the revised proposal real quick: namespace System.Linq
{
public static partial class ImmutableArrayExtensions
{
public static bool Contains<T>(this ImmutableArray<T> immutableArray, T value, IEqualityComparer<T>? comparer);
}
} |
I have updated the proposal to what we have discussed here. Sorry for that it took so long. |
Question for whenever this comes to review: I recall that some time ago the review team made a blanket policy that |
Looks good as proposed, except we changed from an extension method to an instance method (as this is an overload of the existing namespace System.Collections.Immutable;
public static partial struct ImmutableArray<T>
{
public bool Contains(T item, IEqualityComparer<T>? comparer);
} |
Background and motivation
I recently had a significant inner-loop performance regression when I added an optional
IEqualityComparer<T>
to my API. I found out that the reason was that I added the optionalcomparer
argument to theContains
invocation on aImmutableArray<T>
.Apparently there is no such overload, so it the call was directed from:
And fell back to the much slower Linq extension:
This caused a significant amount of boxing to
IEnumerable<T>
each timeContains
was called. Most methods in the API at the moment contain overloads that accept an optionalIEqualityComparer<T>?
, so it was quite surprising that this API did not.See: https://docs.microsoft.com/en-us/dotnet/api/system.collections.immutable.immutablearray-1.contains?view=net-6.0
API Proposal
API Usage
Alternative Designs
No response
Risks
This has a really low risk of breaking something. It should increase the overall performance when
Contains
is used where the programmer was not aware of this issue.The text was updated successfully, but these errors were encountered: