10

如果我有一个不可变的地图,我可能希望(在很短的时间内 - 比如几秒钟)从中添加/删除数十万个项目,那么标准HashMap是一个坏主意吗?假设我想在不到 10 秒的时间内通过 Map 传递 1Gb 的数据,使得 Map 在任何时刻的最大大小仅为 256Mb。

我的印象是地图保留了某种“历史”,但我将始终访问最后更新的表(即我不传递地图),因为它是一个私有成员变量,Actor仅更新/访问从内部反应。

基本上我怀疑这个数据结构可能(部分)有问题,因为我在短时间内读入大量数据时看到 JVM 内存不足。

使用不同的地图实现会更好吗?如果是这样,它是什么?

4

3 回答 3

20

哎哟。为什么必须使用不可变映射?可怜的垃圾收集器!除了 (log n) 时间之外,不可变映射通常每个操作需要 (log n) 个新对象,或者它们实际上只是将可变哈希映射和层变更集包装在顶部(这会减慢速度并增加对象创建的数量)。

不变性很棒,但在我看来,现在不是使用它的时候。如果我是你,我会坚持scala.collection.mutable.HashMap。如果您需要并发访问,请将 Java util.concurrent 包装起来。

您可能还想增加 JVM 中年轻代的大小:-Xmn1G或更多(假设您正在运行-Xmx3G)。此外,使用吞吐量(并行)垃圾收集器。

于 2010-02-19T17:06:41.813 回答
8

那将是可怕的。你说你总是想访问最后更新的表,这意味着你只需要一个短暂的数据结构,不需要为持久的数据结构付出成本——就像交易时间和内存来获得完全有争议的“风格点” ”。当不需要时,你并没有通过盲目地使用持久结构来建立你的业力。

此外,哈希表是一种特别难以持久化的结构。换句话说,“非常非常慢”(基本上它在读取大大超过写入时可用 - 而且您似乎在谈论许多写入)。

顺便说一句ConcurrentHashMap,考虑到地图是从单个参与者访问的(这是我从描述中理解的),因此 a 在此设计中没有意义。

于 2010-02-19T17:29:14.817 回答
4

Scala 所谓的 (*) 不可变 Map 在 Scala 2.7 之前已超出基本使用范围。不要相信我,只需查看它的开放票数即可。解决方案只是“它将在 Scala 2.8 上被其他东西取代”(确实如此)。

因此,如果您想要 Scala 2.7.x 的不可变映射,我建议您在 Scala 以外的地方寻找它。或者只是使用 TreeHashMap 代替。

(*) Scala 的不可变 Map 并不是真正不可变的。它在内部是一个可变的数据结构,需要大量的同步。

于 2010-02-19T17:39:00.927 回答