COMP 405
|
Lazy Evaluation: Additional Information |
![]() ![]() ![]() ![]() ![]() ![]() ![]() |
This is additional information to supplement the main discussion of lazy evaluation.
Here is a little snippet showing eager sequences (List) and lazy sequences (Stream) in Scala, both of which implement the LinearSeq trait (which is the equivalent of an interface in Scala). The following code multiplies the first 10 number in a list of integers. One list is an eager list of 10,000 elements and the other is an infinite lazy list of integers. Notice that the lazy list runs much faster because it doesn't have to instantiate all the integers it is not processing.
// Lazy vs Eager sequences in Scala def time[T](calc: => T): T = { val start = System.nanoTime() val res = calc val end = System.nanoTime() val millisecs = (end - start) / 1000000. printf(">>> Computation took %.3f ms%n", millisecs) res } // time: [T](calc: => T)T // Eager list time { List.iterate(1, 10000)(_+1).take(10).reduceLeft(_*_) } // >>> Computation took 2.699 ms // res11: Int = 3628800 // Lazy infinite stream time { Stream.iterate(1)(_+1).take(10).reduceLeft(_*_) } // >>> Computation took 0.825 ms // res12: Int = 3628800 // Lazy finite stream time { Stream.iterate(1, 10000)(_+1).take(10).reduceLeft(_*_) } // >>> Computation took 0.844 ms // res13: Int = 3628800
From a design perspective notice that the eager and the lazy lists are not the quite same entity. They both implement a top-level interface over which the algorithm is defined, which is nice, because it enables the same algorithm to run on either an eager or lazy list. However, a lazy list never dynamically reclassifies into an eager list so they are not quite substitutable for one another.
Reference: http://www.simplyscala.com/
In Java, the JVM won't initialize the static fields of a class until you
actually run something with it. That makes it so you can use this neat little
trick to get simple, thread-safe lazy initialization of singletons on the JVM:
public class Something { private Something() { } private static class LazyHolder { private static final Something SINGLETON = new Something(); } public static Something getSINGLETON () { return LazyHolder.SINGLETON ; } }
Compare this against the "classic" way to lazily evaluate a Singleton:
public class Something { private Something() { } private static Something SINGLETON = null; public static Something getSINGLETON () { if(null == SINGLETON) SINGLETON = new Something(); return SINGLETON; } }
References:
(Thanks to Nick Vrvilo for this info!)
© 2013 by Stephen Wong