Skip to content

Instantly share code, notes, and snippets.

@stoyle
Created June 13, 2011 13:09
Show Gist options
  • Save stoyle/1022739 to your computer and use it in GitHub Desktop.
Save stoyle/1022739 to your computer and use it in GitHub Desktop.
Fibonacci manipulation with parallel collections, tail recursion, lazy evaluation and memoization
// Definitions:
def t(f: => Any) { val start = System.currentTimeMillis; val res = f; println("Time: " + (System.currentTimeMillis - start) + "ms"); res}
// "Vanilla" version
def fib(num: Long): Long = if (num < 2) num else fib(num - 1) + fib(num - 2)
// Tail recursive version
def fibTR(num: Long) = {
@scala.annotation.tailrec
def fibtr(n: Long, nxt: Long, res: Long): Long = if (n == 0) res else fibtr(n - 1, res + nxt, nxt)
fibtr(num, 1, 0)
}
// Lazy version
def fibL(num: Long): Long = {
def stream(f0: Long, f1: Long): Stream[Long] = Stream.cons(f0, stream(f1, f0 + f1))
val s = stream(0, 1)
s(num.toInt)
}
// Generic momization function
def memoize[K, V](f: K => V): (K => V) = {
val cache = scala.collection.mutable.Map.empty[K, V];
{(k: K) => cache.getOrElseUpdate(k, f(k))}
}
// Memoized vanilla version
val fibM = memoize(fib)
// Demo
val (s, p) = Option(Stream.continually(38L).take(20)).map(_.toList).map(l => (l, l.par)).get
t(s.map(fib))
t(p.map(fib))
//Given better implementations, parallellism doesn't gain you much...
t(s.map(fibTR))
t(p.map(fibTR))
t(s.map(fibL))
t(p.map(fibL))
// Memoization does help a little with the naive approach.
t(s.map(fibM))
t(p.map(fibM))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment