如果我有一个不可变的地图,我可以期望(在很短的时间内 - 比如几秒钟)添加/删除数十万来自的项目是标准HashMap
一个坏主意吗?假设我想通过< 10秒内的Map传递1Gb数据,这样任何时刻Map的最大大小都只有256Mb。
我得到的印象是地图保留了某种“历史记录”,但我总是访问最后更新的表格(即我不会传递地图),因为它是私有的Actor
的成员变量,仅在反应中更新/访问。
基本上我怀疑在短时间内读取大量数据时,此数据结构可能(部分)处于错误for issues I am seeing around JVMs going out of memory。
我会更好地使用不同的地图实现,如果是的话,它是什么?
答案 0 :(得分:20)
哎哟。为什么你必须使用不可变的地图?垃圾收集器差!除了(log n)时间之外,不可变映射通常需要(log n)每个操作的新对象,或者它们实际上只是将可变散列映射和层变换集包装在顶部(这会减慢速度并增加对象创建的数量)。 / p>
不变性很好,但在我看来,这似乎不适合使用它。如果我是你,我会坚持scala.collection.mutable.HashMap
。如果需要并发访问,请改为使用Java util.concurrent。
您还可能希望在JVM中增加年轻代的大小:-Xmn1G
或更多(假设您正在使用-Xmx3G
运行)。另外,使用吞吐量(并行)垃圾收集器。
答案 1 :(得分:8)
那太糟糕了。您说您总是希望访问上次更新的表,这意味着您只需要一个临时数据结构,无需支付持久性数据结构的成本 - 这就像交易时间和记忆,以获得完全可论证的“风格点”。当你没有被要求时,你是而不是通过使用盲目持久的结构来建立你的业力。
此外,哈希表是一种特别难以持久化的结构。换句话说,“非常非常慢”(当读取数量大大超过写入时,基本上它是可用的 - 你似乎谈论了许多写入。)
顺便说一句,ConcurrentHashMap
在这个设计中没有意义,因为地图是从一个演员那里访问的(这是我从描述中理解的)。
答案 2 :(得分:4)
Scala的所谓(*)不可变映射已超出基本用法直到Scala 2.7。不要相信我,只要查看它的开票数量。解决方案就是“它将被Scala 2.8上的其他东西取代”(它确实如此)。
所以,如果你想要一个Scala 2.7.x的不可变映射,我建议用Scala以外的东西来寻找它。或者只使用TreeHashMap。
(*)Scala的不可变Map不是真正不可变的。它内部是一个可变数据结构,需要大量同步。