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 optional comparer argument to the Contains invocation on a ImmutableArray<T>.
Apparently there is no such overload, so it the call was directed from:
public readonly struct ImmutableArray<T>
{
// ...
public bool Contains(T item)
// ...
}
And fell back to the much slower Linq extension:
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 IEnumerable<T> each time Contains was called. Most methods in the API at the moment contain overloads that accept an optional IEqualityComparer<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
namespace System.Linq;
public static partial class ImmutableArrayExtensions
{
public static bool Contains<T>(this ImmutableArray<T> immutableArray, T item, IEqualityComparer<T>? comparer)
{
var self = immutableArray;
return self.IndexOf(item, 0, self.Length, equalityComparer) >= 0;
}
}
API Usage
ImmutableArray<string> items = ImmutableArray.Create("abc", "DEF");
Assert.True(items.Contains("Abc", StringComparer.InvariantCultureIgnoreCase));
Assert.True(items.Contains("Def", StringComparer.InvariantCultureIgnoreCase));
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.
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 optionalcomparerargument to theContainsinvocation 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 timeContainswas 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
Containsis used where the programmer was not aware of this issue.