2016-03-05 37 views
0

我生成一个HashMap哪里可以估算该电源线尺寸,阶乘:按升序排列的素数堆空间与mutable.HashMap

import scala.collection.mutable.HashMap 

    val mm = new HashMap [Int, BigInt] 
    mm.put (0, 1) 
    def fak (i: Int) : BigInt = mm.getOrElseUpdate (i, i * fak (i-1)) 

我频繁请求的阶乘(FAK),和类似的,以达到相当高的值(> 10 Mio阶乘)。

使用约70000个结果调用OutOfMemory-Error:Java堆空间。我开始的程序与

scala -J-Xmx4G TestFak 70000 

以60000作为参数它的工作原理。我想,它建立了70000个可变的地图,它们经常被扔掉并收集垃圾。由于我事先知道需要的大小,是否可以从开始生成适当大小的mutableMap?

错误发生在mm.getOrElseUpdate - 行中。

版本: 斯卡拉版本2.11.6(OpenJDK的64位服务器虚拟机,Java的1.8.0_66-内部)

+0

它不生成70000个地图,只有一个地图有70000个条目。一个没有任何数据的地图条目大约需要36个字节,36 * 70K大约是2.5个字节。加上你存储的BigInts的实际大小(它们也不是很小)。你只是达到了你的记忆极限。 – Dima

+0

@迪玛:嗯,据一个快速估计,36 * 70K应该是2.5M左右,而不是2.5G,不是吗? –

+0

是的,你说得对:) YourKit? – Dima

回答

4

70000阶乘是巨大的!所需的BigInt存储将是相当大的本身!只是想给你一个想法,BigInt可能支持Java中的Array[Int]。这意味着需要存储1!,2!,...,70000的总大小!对于n = 70000将是sum_(1 to n) of 4 * log_(2^32) n!,其大小为四千兆字节。

+0

是的,这听起来很合理。我监督了这一点。因为我必须去分析高达1亿的分解因子,所以我必须找到另一种方法来解决这个挑战,这是其中的一部分。 :) –

+1

哎呀,我得到了数学有点错误。 Ints是4个字节而不是8个。 – badcook

+0

另外,为什么不尝试正常的尾部递归方法?这并不是那么慢... – badcook