🎓 A1Learner
🔍
0 of 45 lessons completed

Lazy vs Eager Cost

Lazy evaluation is work that waits until its result is actually needed. Eager work happens at once, even for values that are never used.

Eager work evaluates everything

A plain map runs at once. This program doubles five values and prints how many were evaluated.

@main def main(): Unit =
  var evaluated = 0
  val doubled = List(1, 2, 3, 4, 5).map(x => { evaluated = evaluated + 1; x * 2 })
  println(evaluated)
  println(doubled.size)
  println(doubled.head)

A view evaluates only what is taken

A view waits until a value is asked for. This program takes only the head and prints how many values were evaluated.

@main def main(): Unit =
  var evaluated = 0
  val viewed = List(1, 2, 3, 4, 5).view.map(x => { evaluated = evaluated + 1; x * 2 })
  val first = viewed.head
  println(evaluated)
  println(first)

Taking two evaluates exactly two

Taking two values from a view evaluates two elements, no more. This program prints the count, the size, and the first and last taken values.

@main def main(): Unit =
  var evaluated = 0
  val firstTwo = List(1, 2, 3, 4, 5).view.map(x => { evaluated = evaluated + 1; x * 2 }).take(2).toList
  println(evaluated)
  println(firstTwo.size)
  println(firstTwo.head)
  println(firstTwo.last)

Example

@main def main(): Unit =
  var eagerCount = 0
  val doubled = List(1, 2, 3, 4, 5).map(x => { eagerCount = eagerCount + 1; x * 2 })
  var viewCount = 0
  val firstTwo = List(1, 2, 3, 4, 5).view.map(x => { viewCount = viewCount + 1; x * 2 }).take(2).toList
  println(eagerCount)
  println(viewCount)
  println(firstTwo.head)
  println(firstTwo.last)

Key points

  • Eager: Work done at once, even for values never used.
  • Lazy: Work delayed until a value is actually needed.
  • View: A view is a lazy version of a collection that delays its steps.
  • Counter: A counter variable records how many elements were actually evaluated.
  • Head: Taking only the head of a lazy result can avoid evaluating the rest.

In this example, the eager map evaluates all five values, then the view map takes only two values, and the printed counts show five against two with the same doubled values 2 and 4.

Note

In Scala, calling view on a collection does not change the original collection.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Scastie

Exercise

You need only the first value of a doubled list. Which approach evaluates less?