Saturday, April 29, 2017

Scala Dessign Patterns: Memoization

Introduction

Memoization is mechanism of recording a function results based on its arguments in order to reduce computation in consecutive calls.

Agenda:

  • Implement Memoization using Scala.
  • Implement Memoization using Scalaz.

 

Code: By Scala


class Hasher extends Memoizer {

  val memoMd5 = memo(md5)

  private def md5(input: String) = {
    println(s"Calling md5 for $input")
    new String(Base64.getEncoder.encode(input.getBytes()))
  }
}

trait Memoizer {

  def memo[X, Y](f: X => Y): X => Y = {
    val cache = mutable.Map[X, Y]()
    (x: X) => cache.getOrElseUpdate(x, f(x))
  }
}

object MemoizationExample extends App {


  val hasher = new Hasher

  println(s"Encode for 'hello' is '${hasher.memoMd5("hello")}'")
  println(s"Encode for 'bye' is '${hasher.memoMd5("bye")}'")
  println(s"Encode for 'hello1' is '${hasher.memoMd5("hello1")}'")
  println(s"Encode for 'hello' is '${hasher.memoMd5("hello")}'")
  println(s"Encode for 'bye' is '${hasher.memoMd5("bye")}'")

}

Code: By Scalaz


class Hasher {

  val memoMd5Scalaz: String => String = Memo.mutableHashMapMemo(md5)

  private def md5(input: String) = {
    println(s"Calling md5 for $input")
    new String(Base64.getEncoder.encode(input.getBytes()))
  }
}

object MemoizationScalazExample extends App {

  val hasher = new Hasher

  println(s"Encode for 'hello' is '${hasher.memoMd5Scalaz("hello")}'")
  println(s"Encode for 'bye' is '${hasher.memoMd5Scalaz("bye")}'")
  println(s"Encode for 'hello1' is '${hasher.memoMd5Scalaz("hello1")}'")
  println(s"Encode for 'hello' is '${hasher.memoMd5Scalaz("hello")}'")
  println(s"Encode for 'bye' is '${hasher.memoMd5Scalaz("bye")}'")
}

Download Code from Github Repo

 

References: