scalaz/scalaz-stream — pull request #237 by stucchio (2014-09-11 17:47:46+00:00)
Title: map speedup

So this big fugly pull request probably conflicts with the internal philosophy of scalaz-stream. On the other hand, *users* of the library will not notice the difference, they'll notice only the performance improvement.

If there is a less java-like way to get the same result, I'd love to see it.

Motivation: the current implementation of `map` will result in `map(x => x)` transforming `Emit(Seq(1,2,3))` into `Emit(Vector(1)) ++ Emit(Vector(2)) ++ Emit(Vector(3)`, not to mention unnecessary calls to `Util.Try`. This new version results in Emit(Seq(1,2,3))`.

The net result is a big speedup:

Time (new map): 195
Time (old map) 1961

In the benchmark code below, `map` is the new version and `map2` is the old version.

def benchmark {
val x = (1 to (1024*1024)).map(x => x.toLong).toSeq

(Process.emitAll(x) : Process[Task,Long]).map(x => x % 7).runLast.run //warm up jvm
val startTimeMap = System.currentTimeMillis
(Process.emitAll(x) : Process[Task,Long]).map(x => x % 7).runLast.run
println("End time: " + (System.currentTimeMillis - startTimeMap))

(Process.emitAll(x) : Process[Task,Long]).map2(x => x % 7).runLast.run //warm up jvm
val startTimeMap2 = System.currentTimeMillis
(Process.emitAll(x) : Process[Task,Long]).map2(x => x % 7).runLast.run
println("End time: " + (System.currentTimeMillis - startTimeMap2))
}