From c33a0d0a9098f8766cd34f524ec4ee79a84f8af4 Mon Sep 17 00:00:00 2001 From: David Barri Date: Mon, 27 Apr 2020 11:39:38 +1000 Subject: [PATCH] Optimise IndexedSeqOps.fold{Left,Right} Inherited foldRight implementation calls reverse.foldLeft --- src/library/scala/collection/IndexedSeq.scala | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/library/scala/collection/IndexedSeq.scala b/src/library/scala/collection/IndexedSeq.scala index bfd85aec6262..a52eba3e3d2f 100644 --- a/src/library/scala/collection/IndexedSeq.scala +++ b/src/library/scala/collection/IndexedSeq.scala @@ -56,6 +56,32 @@ trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C] { self => } else Iterator.empty.next() } + override def foldLeft[B](z: B)(f: (B, A) => B): B = { + // For Vectors with sizes of [100, 1000, 10000] this is [1.2, 1.6, 1.0]x as fast + // as using while+iterator. + var b = z + var i = 0 + while (i < length) { + val a = self(i) + b = f(b, a) + i += 1 + } + b + } + + override def foldRight[B](z: B)(f: (A, B) => B): B = { + // This is 0.28% slower at size=100, 0.8% faster at size=1000, and 2.4% faster at size=10000, + // than using while+reverseIterator. + var b = z + var i = length + while (i > 0) { + i -= 1 + val a = self(i) + b = f(a, b) + } + b + } + override def view: IndexedSeqView[A] = new IndexedSeqView.Id[A](this) @deprecated("Use .view.slice(from, until) instead of .view(from, until)", "2.13.0")