Im doing a performance comparison between executing multiple subsequent transformations on collections in Scala that are strict (eagerly performed evaluation), and non-strict (lazily performed evaluation).
def time[R](block: => R): R = {
val t0 = System.nanoTime()
val result = block // call-by-name
val t1 = System.nanoTime()
println("Elapsed time: " + (t1 - t0)/1e9 + "s")
result
}
/* A view on a collection makes all transformations lazy, which makes it
possible to combine multiple transformations into one. */
// The non-lazy (eager) version:
time {
(1 to 1e7.toInt).map(_ + 2).map(x => {
if(x % 2 != 0) -x else x
}).sum
}
// The lazy version using a view:
time {
(1 to 1e7.toInt).view.map(_ + 2).map(x => {
if(x % 2 != 0) -x else x
}).force.sum
}
On my laptop, the first run of the eager version is slower than the lazy version. See timings below.
Eager version: 2.4 s
Lazy verion: 0.7 s
However, starting from the second run, both of them take about 0.7 seconds. Why?
Runtime environment:
- Scala 2.11.7
- Java 1.8
- OS X 10.10