使用hashmap scala缓存函数结果
下面是我为在scala中解决Euler#14项目而编写的一些代码 输出也显示在下面。我的问题是,我期望缓存版本具有更好的性能,但事实恰恰相反。我想我做错了什么,因为我不认为HashMap的开销足以让它变得如此缓慢 有什么建议吗使用hashmap scala缓存函数结果,scala,caching,parallel-processing,hashmap,Scala,Caching,Parallel Processing,Hashmap,下面是我为在scala中解决Euler#14项目而编写的一些代码 输出也显示在下面。我的问题是,我期望缓存版本具有更好的性能,但事实恰恰相反。我想我做错了什么,因为我不认为HashMap的开销足以让它变得如此缓慢 有什么建议吗 object Problem14 { def main(args: Array[String]) { val collatzCacheMap = collection.mutable.HashMap[Long,Long]() def collatzLengthWithC
object Problem14 {
def main(args: Array[String]) {
val collatzCacheMap = collection.mutable.HashMap[Long,Long]()
def collatzLengthWithCache(num: Long): Long = {
def collatzR(currNum: Long, solution: Long): Long = {
val cacheVal = collatzCacheMap.get(currNum)
if(cacheVal != None) {
val answer = solution + cacheVal.get
collatzCacheMap.put(num, answer);
answer;
}
else if(currNum == 1) { collatzCacheMap.put(num, solution + 1); solution + 1; }
else if(currNum % 2 == 0) collatzR(currNum/2, solution + 1)
else collatzR(3*currNum + 1, solution + 1)
}
collatzR(num, 0)
}
def collatzLength(num: Long): Long = {
def collatzR(currNum: Long, solution: Long): Long = {
if(currNum == 1) solution + 1
else if(currNum % 2 == 0) collatzR(currNum/2, solution + 1)
else collatzR(currNum*3 + 1, solution + 1)
}
collatzR(num, 0)
}
var startTime = System.currentTimeMillis()
//val answer = (1L to 1000000).reduceLeft((x,y) => if(collatzLengthWithCache(x) > collatzLengthWithCache(y)) x else y)
val answer = (1L to 1000000).zip((1L to 1000000).map(collatzLengthWithCache)).reduceLeft((x,y) => if(x._2 > y._2) x else y)
println(answer)
println("Cached time: " + (System.currentTimeMillis() - startTime))
collatzCacheMap.clear()
startTime = System.currentTimeMillis()
//val answer2 = (1L to 1000000).par.reduceLeft((x,y) => if(collatzLengthWithCache(x) > collatzLengthWithCache(y)) x else y)
val answer2 = (1L to 1000000).par.zip((1L to 1000000).par.map(collatzLengthWithCache)).reduceLeft((x,y) => if(x._2 > y._2) x else y)
println(answer2)
println("Cached time parallel: " + (System.currentTimeMillis() - startTime))
startTime = System.currentTimeMillis()
//val answer3 = (1L to 1000000).reduceLeft((x,y) => if(collatzLength(x) > collatzLength(y)) x else y)
val answer3 = (1L to 1000000).zip((1L to 1000000).map(collatzLength)).reduceLeft((x,y) => if(x._2 > y._2) x else y)
println(answer3)
println("No Cached time: " + (System.currentTimeMillis() - startTime))
startTime = System.currentTimeMillis()
//val answer4 = (1L to 1000000).par.reduceLeft((x,y) => if(collatzLength(x) > collatzLength(y)) x else y)
val answer4 = (1L to 1000000).par.zip((1L to 1000000).par.map(collatzLength)).reduceLeft((x,y) => if(x._2 > y._2) x else y)
println(answer4)
println("No Cached time parallel: " + (System.currentTimeMillis() - startTime))
}
}
输出:
(837799525)缓存时间:1070
(837799525)
缓存时间并行:954
(837799525)
无缓存时间:450
(837799525)
没有缓存的时间并行:241
它是如何扩展的?例如,将缓存和未缓存映射中的项目数量增加10倍,以减少hashmap实现的相对开销,并查看缓存版本是否仍然较慢。首先,我以更大的数量级运行它(这很慢,毫不奇怪),应该需要一段时间(如果它解决了这个问题,long可能太小…)增加缓存和未缓存映射中的项目数量是什么意思?缓存只有一个映射,我把每个结果都放在里面缓存时间也慢了10亿到10亿对不起,我明白了你的意思,我发现某个地方的初始大小是16,为什么文档上没有呢?所以我扩展了HashMap并覆盖initalSize到~1M个条目(我将输入的条目数)它没有改变任何东西…它是如何扩展的?例如,将缓存和未缓存映射中的项目数量增加10倍,以减少hashmap实现的相对开销,并查看缓存版本是否仍然较慢。首先,我以更大的数量级运行它(这很慢,毫不奇怪),应该需要一段时间(如果它解决了这个问题,long可能太小…)增加缓存和未缓存映射中的项目数量是什么意思?缓存只有一个映射,我把每个结果都放在里面缓存时间也慢了10亿到10亿对不起,我明白了你的意思,我发现某个地方的初始大小是16,为什么文档上没有呢?所以我扩展了HashMap并覆盖了initalSize到~1M个条目(我将输入的条目数),它没有改变任何东西。。。