Skip to content

Commit 16a76b0

Browse files
committed
Optimized filter for immutable.SetN
Avoids creating iterators and using builders and reuses the input collection when the predicate selects all elements.
1 parent c20ea22 commit 16a76b0

File tree

1 file changed

+46
-0
lines changed
  • library/src/scala/collection/immutable

1 file changed

+46
-0
lines changed

library/src/scala/collection/immutable/Set.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ object Set extends IterableFactory[Set] {
168168
override def foreach[U](f: A => U): Unit = f(elem1)
169169
override def exists(p: A => Boolean): Boolean = p(elem1)
170170
override def forall(p: A => Boolean): Boolean = p(elem1)
171+
override protected[collection] def filterImpl(pred: A => Boolean, isFlipped: Boolean): Set[A] =
172+
if (pred(elem1) != isFlipped) this else Set.empty
173+
171174
override def find(p: A => Boolean): Option[A] =
172175
if (p(elem1)) Some(elem1)
173176
else None
@@ -203,6 +206,18 @@ object Set extends IterableFactory[Set] {
203206
override def forall(p: A => Boolean): Boolean = {
204207
p(elem1) && p(elem2)
205208
}
209+
override protected[collection] def filterImpl(pred: A => Boolean, isFlipped: Boolean): Set[A] = {
210+
var r1: A = null.asInstanceOf[A]
211+
var n = 0
212+
if (pred(elem1) != isFlipped) { r1 = elem1; n += 1}
213+
if (pred(elem2) != isFlipped) { if (n == 0) r1 = elem2; n += 1}
214+
215+
n match {
216+
case 0 => Set.empty
217+
case 1 => new Set1(r1)
218+
case 2 => this
219+
}
220+
}
206221
override def find(p: A => Boolean): Option[A] = {
207222
if (p(elem1)) Some(elem1)
208223
else if (p(elem2)) Some(elem2)
@@ -242,6 +257,20 @@ object Set extends IterableFactory[Set] {
242257
override def forall(p: A => Boolean): Boolean = {
243258
p(elem1) && p(elem2) && p(elem3)
244259
}
260+
override protected[collection] def filterImpl(pred: A => Boolean, isFlipped: Boolean): Set[A] = {
261+
var r1, r2: A = null.asInstanceOf[A]
262+
var n = 0
263+
if (pred(elem1) != isFlipped) { r1 = elem1; n += 1}
264+
if (pred(elem2) != isFlipped) { if (n == 0) r1 = elem2 else r2 = elem2; n += 1}
265+
if (pred(elem3) != isFlipped) { if (n == 0) r1 = elem3 else if (n == 1) r2 = elem3; n += 1}
266+
267+
n match {
268+
case 0 => Set.empty
269+
case 1 => new Set1(r1)
270+
case 2 => new Set2(r1, r2)
271+
case 3 => this
272+
}
273+
}
245274
override def find(p: A => Boolean): Option[A] = {
246275
if (p(elem1)) Some(elem1)
247276
else if (p(elem2)) Some(elem2)
@@ -283,6 +312,23 @@ object Set extends IterableFactory[Set] {
283312
override def forall(p: A => Boolean): Boolean = {
284313
p(elem1) && p(elem2) && p(elem3) && p(elem4)
285314
}
315+
override protected[collection] def filterImpl(pred: A => Boolean, isFlipped: Boolean): Set[A] = {
316+
var r1, r2, r3: A = null.asInstanceOf[A]
317+
var n = 0
318+
if (pred(elem1) != isFlipped) { r1 = elem1; n += 1}
319+
if (pred(elem2) != isFlipped) { if (n == 0) r1 = elem2 else r2 = elem2; n += 1}
320+
if (pred(elem3) != isFlipped) { if (n == 0) r1 = elem3 else if (n == 1) r2 = elem3 else r3 = elem3; n += 1}
321+
if (pred(elem4) != isFlipped) { if (n == 0) r1 = elem4 else if (n == 1) r2 = elem4 else if (n == 2) r3 = elem4; n += 1}
322+
323+
n match {
324+
case 0 => Set.empty
325+
case 1 => new Set1(r1)
326+
case 2 => new Set2(r1, r2)
327+
case 3 => new Set3(r1, r2, r3)
328+
case 4 => this
329+
}
330+
}
331+
286332
override def find(p: A => Boolean): Option[A] = {
287333
if (p(elem1)) Some(elem1)
288334
else if (p(elem2)) Some(elem2)

0 commit comments

Comments
 (0)