Avoid delegate wrapper in `ICollection.RemoveAll` extension hot path

see 6d40c08c3
This commit is contained in:
James Groom 2024-03-12 15:24:41 +10:00 committed by GitHub
parent 24bd99eb07
commit e55c6c2688
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 3 additions and 3 deletions

View File

@ -233,9 +233,9 @@ namespace BizHawk.Common.CollectionExtensions
/// (This is an extension method which reimplements <see cref="List{T}.RemoveAll"/> for other <see cref="ICollection{T}">collections</see>. /// (This is an extension method which reimplements <see cref="List{T}.RemoveAll"/> for other <see cref="ICollection{T}">collections</see>.
/// It defers to the existing <see cref="List{T}.RemoveAll">RemoveAll</see> if the receiver's type is <see cref="List{T}"/> or a subclass.) /// It defers to the existing <see cref="List{T}.RemoveAll">RemoveAll</see> if the receiver's type is <see cref="List{T}"/> or a subclass.)
/// </remarks> /// </remarks>
public static int RemoveAll<T>(this ICollection<T> list, Predicate<T> match) public static int RemoveAll<T>(this ICollection<T> list, Func<T, bool> match)
{ {
if (list is List<T> listImpl) return listImpl.RemoveAll(match); if (list is List<T> listImpl) return listImpl.RemoveAll(item => match(item)); // can't simply cast to Predicate<T>, but thankfully we only need to allocate 1 extra delegate
var c = list.Count; var c = list.Count;
if (list is IList<T> iList) if (list is IList<T> iList)
{ {
@ -246,7 +246,7 @@ namespace BizHawk.Common.CollectionExtensions
} }
else else
{ {
foreach (var item in list.Where(item => match(item)) // can't simply cast to Func<T, bool> foreach (var item in list.Where(match)
.ToArray()) // very important .ToArray()) // very important
{ {
list.Remove(item); list.Remove(item);