Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a1eaaf2

Browse files
committed
Optimize ImmutableArray<T>.RemoveRange for 0/1 arguments
RemoveRange(IEnumerable<T>, ...) is fairly expensive allocation-wise, allocating a SortedSet<int>, an enumerator, a new resulting array, etcr. We can easily avoid such costs if the immutable items array contains 0 or 1 elements. RemoveRange(int, int) also allocates a new array. We can avoid that cost if the length of the requested range to remove is empty.
1 parent 45bff38 commit a1eaaf2

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray`1.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,11 @@ public ImmutableArray<T> RemoveRange(int index, int length)
756756
Requires.Range(index >= 0 && index < self.Length, "index");
757757
Requires.Range(length >= 0 && index + length <= self.Length, "length");
758758

759+
if (length == 0)
760+
{
761+
return self;
762+
}
763+
759764
T[] tmp = new T[self.Length - length];
760765
Array.Copy(self.array, 0, tmp, 0, index);
761766
Array.Copy(self.array, index + length, tmp, index, self.Length - index - length);
@@ -817,7 +822,7 @@ public ImmutableArray<T> RemoveRange(IEnumerable<T> items, IEqualityComparer<T>
817822
[Pure]
818823
public ImmutableArray<T> RemoveRange(ImmutableArray<T> items)
819824
{
820-
return this.RemoveRange(items.array);
825+
return this.RemoveRange(items, EqualityComparer<T>.Default);
821826
}
822827

823828
/// <summary>
@@ -833,7 +838,22 @@ public ImmutableArray<T> RemoveRange(ImmutableArray<T> items)
833838
[Pure]
834839
public ImmutableArray<T> RemoveRange(ImmutableArray<T> items, IEqualityComparer<T> equalityComparer)
835840
{
836-
return this.RemoveRange(items.array, equalityComparer);
841+
var self = this;
842+
Requires.NotNull(items.array, "items");
843+
844+
if (items.IsEmpty)
845+
{
846+
self.ThrowNullRefIfNotInitialized();
847+
return self;
848+
}
849+
else if (items.Length == 1)
850+
{
851+
return self.Remove(items[0], equalityComparer);
852+
}
853+
else
854+
{
855+
return self.RemoveRange(items.array, equalityComparer);
856+
}
837857
}
838858

839859
/// <summary>

0 commit comments

Comments
 (0)