Last active
May 16, 2016 17:30
-
-
Save wuservices/4568ab3959e5234a9b10e1b1e2cbd0ab to your computer and use it in GitHub Desktop.
Informal test to see how much overhead Scalacache introduces on top of Caffeine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object TimeScalacacheGetCaffeine { | |
import scala.concurrent.duration._ | |
import scala.concurrent.{Await, Future} | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import com.github.benmanes.caffeine.cache.Caffeine | |
import com.github.blemale.scaffeine.{Cache, Scaffeine} | |
import scalacache._ | |
import caffeine._ | |
import memoization._ | |
val underlyingCache = Caffeine.newBuilder().build[String, Object]() | |
implicit val scalaCache = ScalaCache(CaffeineCache(underlyingCache)) | |
val scaffeineCache: Cache[Long, Option[String]] = Scaffeine().build[Long, Option[String]]() | |
// Test data | |
val testItem: Option[String] = Option("Some item") | |
val testItemKey = 5000 | |
def itemUncached(id: Long): Option[String] = { | |
testItem | |
} | |
def itemCachedNoMemoize(id: Long): Future[Option[String]] = { | |
get[String, NoSerialization](id) | |
} | |
def itemCachedMemoize(id: Long): Future[Option[String]] = memoize { | |
Future { | |
itemUncached(id) | |
} | |
} | |
def time[T](message: String, startTime: Long = System.nanoTime)(block: => T) = { | |
val result = block | |
println(s"$message in ${elapsedTimeMs(startTime)} ms") | |
result | |
} | |
def elapsedTimeMs(startNanoTime: Long) = ((System.nanoTime - startNanoTime) / 1e5).round / 10.toDouble | |
def main(args: Array[String]): Unit = { | |
val numIterations = 1000000 | |
for (i <- 1 to 3) { | |
println(s"Run #$i ($numIterations iterations per run)") | |
time("Uncached / return directly") { | |
for(_ <- 1 to numIterations)(itemUncached(testItemKey)) | |
} | |
// Populate cache without memoize using scalacache | |
put(testItemKey)(itemUncached(testItemKey)) | |
time("scalacache get no memoize") { | |
for(_ <- 1 to numIterations)(Await.result(itemCachedNoMemoize(testItemKey), Duration.Inf)) | |
} | |
// Populate cache through memoize | |
itemCachedMemoize(testItemKey) | |
time("scalacache get with memoize") { | |
for(_ <- 1 to numIterations)(Await.result(itemCachedMemoize(testItemKey), Duration.Inf)) | |
} | |
time("get from Caffeine directly") { | |
for(_ <- 1 to numIterations)(underlyingCache.getIfPresent(testItemKey)) | |
} | |
time("get from underlying ConcurrentHashMap") { | |
for(_ <- 1 to numIterations)(underlyingCache.asMap.get(testItemKey)) | |
} | |
// Populate scaffeine cache | |
scaffeineCache.put(testItemKey, itemUncached(testItemKey)) | |
time("get using scaffeine") { | |
for(_ <- 1 to numIterations)(scaffeineCache.getIfPresent(testItemKey)) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I got something like this
It seems like scalacache without memoize is 30x+ times slower than Caffeine or ConcurrentHashMap. Once we add memoize, it seems 1500x+ slower. For comparison, I also tried using scaffeine which only seems to add ~50% overhead.