diff options
author | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2012-08-20 11:27:25 +0100 |
---|---|---|
committer | Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com> | 2012-08-20 11:27:25 +0100 |
commit | df9f470f14262b9b1002f022c2620d8c38835805 (patch) | |
tree | 4e9a18a1aff2af3c8a89c6c71e8aab34b1b4e3af /src/library | |
parent | ebb719fb92a50476ba51e4be8e87571ff4949551 (diff) | |
download | scala-df9f470f14262b9b1002f022c2620d8c38835805.tar.gz scala-df9f470f14262b9b1002f022c2620d8c38835805.tar.bz2 scala-df9f470f14262b9b1002f022c2620d8c38835805.zip |
Attempts to improve inlining behavior for map, flatMap.
Reduced method size of map/flatMap to under 35 bytes to make them
inlinable. Also specialized filterNot code so that it does not create
a second closure. Finally, avoided default argument for sizeHint to
reduce size of methods calling it.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/collection/TraversableLike.scala | 18 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/Builder.scala | 20 |
2 files changed, 33 insertions, 5 deletions
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala index 0345f05355..b2051bf209 100644 --- a/src/library/scala/collection/TraversableLike.scala +++ b/src/library/scala/collection/TraversableLike.scala @@ -235,14 +235,19 @@ trait TraversableLike[+A, +Repr] extends Any (that ++ seq)(breakOut) def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { - val b = bf(repr) - b.sizeHint(this) + def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined + val b = bf(repr) + b.sizeHint(this) + b + } + val b = builder for (x <- this) b += f(x) b.result } def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { - val b = bf(repr) + def builder = bf(repr) // extracted to keep method size under 35 bytes, so that it can be JIT-inlined + val b = builder for (x <- this) b ++= f(x).seq b.result } @@ -266,7 +271,12 @@ trait TraversableLike[+A, +Repr] extends Any * @return a new $coll consisting of all elements of this $coll that do not satisfy the given * predicate `p`. The order of the elements is preserved. */ - def filterNot(p: A => Boolean): Repr = filter(!p(_)) + def filterNot(p: A => Boolean): Repr = { + val b = newBuilder + for (x <- this) + if (!p(x)) b += x + b.result + } def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) diff --git a/src/library/scala/collection/mutable/Builder.scala b/src/library/scala/collection/mutable/Builder.scala index bbf4f5889d..b6887df61e 100644 --- a/src/library/scala/collection/mutable/Builder.scala +++ b/src/library/scala/collection/mutable/Builder.scala @@ -62,9 +62,27 @@ trait Builder[-Elem, +To] extends Growable[Elem] { * wrong, i.e. a different number of elements is added. * * @param coll the collection which serves as a hint for the result's size. + */ + def sizeHint(coll: TraversableLike[_, _]) { + if (coll.isInstanceOf[collection.IndexedSeqLike[_,_]]) { + sizeHint(coll.size) + } + } + + /** Gives a hint that one expects the `result` of this builder + * to have the same size as the given collection, plus some delta. This will + * provide a hint only if the collection is known to have a cheap + * `size` method. Currently this is assumed to be the case if and only if + * the collection is of type `IndexedSeqLike`. + * Some builder classes + * will optimize their representation based on the hint. However, + * builder implementations are still required to work correctly even if the hint is + * wrong, i.e. a different number of elements is added. + * + * @param coll the collection which serves as a hint for the result's size. * @param delta a correction to add to the `coll.size` to produce the size hint. */ - def sizeHint(coll: TraversableLike[_, _], delta: Int = 0) { + def sizeHint(coll: TraversableLike[_, _], delta: Int) { if (coll.isInstanceOf[collection.IndexedSeqLike[_,_]]) { sizeHint(coll.size + delta) } |