关于我们的数据结构,令人着迷的事情之一是,即使我们对它们非常熟悉,我们仍然很难说出像HashMap这样基本的东西在1GB的内存中可以容纳多少个项目。 我们可能会在学校,高级开发人员那里学到这一点,或者由于数据结构选择不当而导致服务器崩溃时,可能会遇到困难。 所以我决定这样做。 我从约20个最流行的Java,Scala,Guava和Trove集合中进行了测试,并测试了它们中每个具有1GB内存的JVM可以容纳多少个随机整数(通过-Xmx)。 对于每个数据结构,我们都附加int直到收到OutOfMemoryError为止,该错误结束了测试。 为了确保一致性,我们在JDK 7上运行了每个测试5次。 对于这种基本测试,我发现其中一些结果令人惊讶。 *我想我们不在同一页上,因为这不是竞争。 不同的集合具有不同的语义。 我也没有包括时间,因为重点不是微基准测试性能,而是让我们了解我们日常使用的收藏实际上可以容纳多少。
结果
- Scala的集合具有比Java更大的容量。 Scala集合似乎比Java集合更有效率。 虽然某些集合(例如TreeSets)的表现大致相同,但其他集合(例如Scala的HashMaps)却能够容纳近15%的项目。 HashSet可以容纳的项目比Java同类项目多8%。 我很想听听社区人士为什么这么认为。 Scala的ArrayBuffer相对于ArrayList具有一点优势。
- 唯一的例外是Scala的链表,它比Java的LinkedList所保存的数据少18%。 这里的一个约束是,为了追加到列表,它需要接收另一个链接列表而不是直接值。 即使这样,假设临时列表是GC的,它本身也不会影响列表在1GB JVM中的容纳容量。
*我们正在计算持有的int数,这意味着每张地图插入2 int。
- 如果您不使用Trove,那么您会错过。 从第一天开始,我们就一直在Takipi的后端上使用Trove的收藏。 好吧,可悲的是从第一天开始,因为这将为我们节省大量时间来优化服务器代码。 TIntArrayList能够容纳250%的Scala和Java盒装同类产品,这些数字足以说明一切。
- 对于地图观察到相似的比率。 令人惊讶的是,Trove的映射性能超过Java和Scala列表超过50%。 请记住,您还具有从int到Object的Trove集合映射,反之亦然,因此您不需要完全原始的映射即可享受容量的好处。
- 即使这样,我们仍然看到Trove的TIntLinkedList可以容纳比装箱它们的原语的Java ArrayList或Scala ArrayBuffer少的数据。 这确实使您可以查看在您的代码中大量使用的链表并重新考虑-我绝对需要它吗?
- 由于使用Trove集合与标准库的集合实际上没有开销,因此我不会将使用它们归类为“按需优化”方案。 这是因为内存消耗错误通常会在规模上显现,这是最难发现的错误,因此您必须开始进行生产调试 (当然Trove不会使您摆脱固有的效率低下的算法)。 有时可能是分析核心转储和观看巨人比赛之间的区别。
- 番石榴–大地图,小套。 番石榴的多套产品比Java和Scala的同类产品价格更高。 与Scala的设置相比,它们能够保存少19%的数据。 不利的一面当然是,他们可以执行使用标准集合语义不可能完成的事情。 只要多集将在您的内存结构中扮演重要角色,请确保您需要这些。
- 对于多贴图,我们看到的情况恰恰相反。 Guava的MultiHashMap比Java的hashmap拥有的值多20%,比Scala的多10%。 看到虽然Guava的多集在容量方面不及Java和Scala等价物,但MultiMap实际上却胜过Java和Scala。
那里有更多的集合类型(队列,堆栈等),但是我想从基础开始,并为每个受欢迎的需求添加更多。 因此,如果您想在列表中看到另一个收藏夹,或者想进一步了解某些功能上的差异,请在下面的评论部分中知道该怎么做。
- 该代码可在此处获得 。
翻译自: https://www.javacodegeeks.com/2014/01/java-scala-guava-and-trove-collections-how-much-data-can-they-hold.html