scala 如何在scala中缓存结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3651313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to cache results in scala?
提问by Jeriho
This pagehas a description of Map's getOrElseUpdateusage method:
这个页面有Map的getOrElseUpdate使用方法说明:
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 catchedFun1which will check if cacheFun1contains key and return value associated with it. Otherwise, it will invoke fun1, then cache fun1's result in cacheFun1, then return fun1's result.
因此,您可以使用catchedFun1which 将检查是否cacheFun1包含与其关联的键和返回值。否则,它将调用fun1,然后将fun1的结果缓存在 中cacheFun1,然后返回fun1的结果。
I can see one potential danger - cacheFun1can became to large. So cacheFun1must be cleaned somehow by garbage collector?
我可以看到一个潜在的危险 -cacheFun1可以变得很大。所以cacheFun1必须通过垃圾收集器以某种方式清理?
P.S. What about scala.collection.mutable.WeakHashMap and java.lang.ref.*?
PSscala.collection.mutable.WeakHashMap and java.lang.ref.*呢?
回答by oluies
See the Memo patternand the Scalaz implementationof said paper.
Also check out a STM implementation such as Akka.
还可以查看 STM 实现,例如Akka。
Not that this is only local caching so you might want to lookinto a distributed cache or STMsuch as CCSTM, Terracottaor Hazelcast
并不是说这只是本地缓存,因此您可能想要查看分布式缓存或STM,例如CCSTM、Terracotta或Hazelcast
回答by Nimrod007
Take a look at spray caching (super simple to use)
看看spray caching(超级简单好用)
http://spray.io/documentation/1.1-SNAPSHOT/spray-caching/
http://spray.io/documentation/1.1-SNAPSHOT/spray-caching/
makes the job easy and has some nice features
使工作变得轻松并具有一些不错的功能
for example :
例如 :
import spray.caching.{LruCache, Cache}
//this is using Play for a controller example getting something from a user and caching it
object CacheExampleWithPlay extends Controller{
//this will actually create a ExpiringLruCache and hold data for 48 hours
val myCache: Cache[String] = LruCache(timeToLive = new FiniteDuration(48, HOURS))
def putSomeThingInTheCache(@PathParam("getSomeThing") someThing: String) = Action {
//put received data from the user in the cache
myCache(someThing, () => future(someThing))
Ok(someThing)
}
def checkIfSomeThingInTheCache(@PathParam("checkSomeThing") someThing: String) = Action {
if (myCache.get(someThing).isDefined)
Ok(s"just $someThing found this in the cache")
else
NotFound(s"$someThing NOT found this in the cache")
}
}
回答by Debilski
回答by Johnny
For simple caching needs, I'm still using Guava cache solutionin Scala as well. Lightweight and battle tested.
对于简单的缓存需求,我仍然在 Scala 中使用Guava 缓存解决方案。轻巧且经过战斗测试。
If it fit's your requirements and constraints generally outlined below, it could be a great option:
如果它符合您的要求和限制,通常如下所述,它可能是一个不错的选择:
- Willing to spend some memory to improve speed.
- Expecting that keys will sometimes get queried more than once.
- Your cache will not need to store more data than what would fit in RAM. (Guava caches are local to a single run of your application. They do not store data in files, or on outside servers.)
- 愿意花一些内存来提高速度。
- 期望密钥有时会被查询不止一次。
- 您的缓存不需要存储比 RAM 中所能容纳的更多的数据。(Guava 缓存对于您的应用程序的单次运行来说是本地的。它们不会将数据存储在文件中,也不会存储在外部服务器上。)
Example for using it will be something like this:
使用它的示例将是这样的:
lazy val cachedData = CacheBuilder.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.maximumSize(10)
.build(
new CacheLoader[Key, Data] {
def load(key: Key): Data = {
veryExpansiveDataCreation(key)
}
}
)
To read from it, you can use something like:
要从中读取,您可以使用以下内容:
def cachedData(ketToData: Key): Data = {
try {
return cachedData.get(ketToData)
} catch {
case ee: Exception => throw new YourSpecialException(ee.getMessage);
}
}
回答by dimitrisli
Since it hasn't been mentioned before let me put on the table the light Spray-Cachingthat can be used independently from Spray and provides expected size, time-to-live, time-to-idle eviction strategies.
由于之前没有提到过,让我把轻量级的Spray-Caching放在桌面上,它可以独立于 Spray 使用,并提供预期的大小、生存时间、空闲时间驱逐策略。

