How to cache results in scala?

Viewed 25868

This page has a description of Map's getOrElseUpdate usage method:

object WithCache{
  val cacheFun1 = collection.mutable.Map[Int, Int]()
  def fun1(i:Int) = i*i
  def catchedFun1(i:Int) = cacheFun1.getOrElseUpdate(i, fun1(i))
}

So you can use catchedFun1 which will check if cacheFun1 contains key and return value associated with it. Otherwise, it will invoke fun1, then cache fun1's result in cacheFun1, then return fun1's result.

I can see one potential danger - cacheFun1 can became to large. So cacheFun1 must be cleaned somehow by garbage collector?

P.S. What about scala.collection.mutable.WeakHashMap and java.lang.ref.* ?

6 Answers

We are using Scaffeine (Scala + Caffeine), and you can read abouts its pros/cons compared to other frameworks over here.

You add your sbt,

"com.github.blemale" %% "scaffeine" % "4.0.1"

Build your cache

import com.github.blemale.scaffeine.{Cache, Scaffeine}
import scala.concurrent.duration._

val cachedItems: Cache[String, Int] = 
  Scaffeine()
    .recordStats()
    .expireAtferWrite(60.seconds)
    .maximumSize(500)
    .build[String, Int]()

cachedItems.put("key", 1) // Add items

cache.getIfPresent("key") // Returns an option
Related