应用JMH测试大型HashMap的性能

  • 时间:
  • 浏览:10
  • 来源:彩神欢乐生肖_神彩欢乐生肖官方

10G也是慢,跑太大了,不乐意跑了,果断放弃。我们直接来看这种 的实现。

JMH使用注解来标记的基准测试。底下另4个 注解的选项的意思分别是:

2950 val testSet: List[(Long, Long)] = List.range(0, MapSize).map { _ =>

完后 ,依次使用Eclipse Collections, Hppc, Koloboke和Trove,就完成了我们的Benchmark编写:

完后 ,在项目中的模块定义中,使用它:

我们能第一时间想到的最朴素最直接的候确定以后Java自带的HashMap了,这是我们平时使用最多也是最熟悉的实现。只不过在这里完后 性能和内存消耗的原困,它稍微有点儿太大花费。我我虽然市面上有什么都有有这种 优秀的集合库实现的,我在这里大致列一下我这边会测试的哪好多个:

综合内存使用以及性能,我此人 我虽然在此次比赛初赛中,他说HPPC是个比较好的确定。

完后 的初赛简单思路不能看这里。

完后 ,我们写另4个 遍历testSet的函数:

FastUtil: 另4个 意大利的计算机博士开发的集合库。

HPPC: 专门为原始类型设计的集合库。

7 8import scala.util.Random

1920@State(Scope.Benchmark)

State表明不能在类底下创建成员变量,供所有测试复用,复用的范围是在Benchmark当中;

3536 def testSetTraverse(hashMap: LongLongOp) = {

好,介绍以后开始,我们接下来看一下我们怎么来编写系统线程池池测试各种Map。

什么都有有,初赛使用Java的HashMap实现的小伙伴,是都有应该赶紧思考一下换一下内存索引的形态,来补救OOM呢?

@Benchmark表示这是另4个 要运行的基准测试。@OperationsPerInvocation注解会接收另4个 数值,表示这种 测试的土最好的土办法运行了哪好多个次。在我们这边是OperationPerInvocation次。注意,前面的变量在jmh.HashMapBenchmark的伴生对象中定义:

2 3import com.koloboke.collect.impl.hash.MutableLHashParallelKVLongLongMapGO

有以后,我们就不能启动sbt,输入前面提到的jmh:run命令了。我们先跑一波看看:

有以后,我们就不能在sbt的console下,执行如下命令,来运行jmh测试了:

4546 def printlnObjectSize(message: String, obj: AnyRef) = {

1314trait LongLongOp {

2425 import HashMapBenchmark._

7475 val map = new LongLongHashMap(MapSize, 0.99) with LongLongOp

完后 是为了比赛而接触的这种 库,什么都有有我只按照比赛场景给我们做了测试。我们会预生成650W对8字节的Key,和8字节的长整型Value,完后 会将这种 key详细写入各人的HashMap中去,有以后再从中读取出来,并与暂存的Value作比较,判断正确性。整个的测试过程是交给JMH来做的。下面介绍一下JMH工具。

写这篇是完后 PolarDB比赛有点儿要的这种 是控制内存。C++只有2G,Java也只有3G,而650W的键值对,即使以后Long类型,也时要16 * 64 * 10e6 ≈ 1G的内存,这还不包括这种 对象引用的相关开销,什么都有有内存控制在这里是非常重要的,完后 稍不小心就会被CGroup无情地kill掉。有以后在比赛以后开始没多久的完后 你会研究了一下使用怎么的HashMap不能达到内存最简的情况报告。在这种 过程中,顺便使用了JMH来分析了一下哪好多个侯选库的性能。完后 初赛相对来说比较简单,有以后HashMap实际上在复赛完后 的Range操作上这么 发挥余地,什么都有有我决定将这篇写下来分享给我们,希望能帮助更多对比赛有兴趣的同学找到另4个 比较好的入手点。

5758 val map = new LongLongHashMap(MapSize)

5152 @Benchmark

8788 @Benchmark

其中printLnObjectSize是用来打印map占用内存数量的:

Scala这边,我们所熟悉的Ktoso大佬包了另4个 sbt-jmh插件,使得我们不能方便地利用SBT来运行JMH测试。要使用sbt-jmh插件,首先,在plugins.sbt文件底下加上插件:

Koloboke: 又一位大神的作品,目标是低内存高性能。

果断杀掉,加上jvm参数完后 再测试:

为了做基准测试,我们首先创建另4个 650W大小的列表,列表的元素是另4个 二元组,都有Long:

这里时要说一下,完后 内存有要求,什么都有有我们时要并肩打印一下HashMap的内存大小。我所使用的是网上找到的另4个 应该是从Spark代码中抠出来的另4个 实现,速率单位快,估值准。只时要在build.sbt中如下引入即可。

跑起来完后 我感觉我错了,电脑风扇在狂转,有以后预热半天都跑不完。jstat看一下gc情况报告试试先,发现50多秒都有FGC。。

首先,我们先创建另4个 类,如下:

完后 我我虽然这里的hashmap的库使用我我虽然大同小异,为了补救重复,什么都有有我利用Scala的这种 形态来进行代码编写。首先我定义了另4个 特质为LongLongOp:

2627 val random = new Random(42)

底下的参数解释下来,以后要求项目对符合正则表达式.*FalseSharing.*的基准测试,运行3次,运行完后 要进行3次预热,只时要跑一遍,使用另4个 系统线程池池。

这里有个关于比赛的小技巧,完后 Key都有8字节的,什么都有有我我虽然每个Key都很容易转化成Long类型的。什么都有有我们在测试底下也只测试对于Long类型的写入性能,以Java的HashMap为例:

23 val testSet: List[(Long, Long)] = List.range(0, 6500000).map { _ =>

5556 import org.eclipse.collections.impl.map.mutable.primitive.LongLongHashMap

6869 @Benchmark

Trove: 挂在bitbucket底下的另4个 开源项目。

JMH是由OpenJDK开发的,用来构建、运行和分析Java或这种 Jvm语言所写的系统线程池池的基准测试框架。它不能帮助我们自动构建和运行基准测试,有以后汇总得到结果。现在一般Java世界底下的主流Benchmark以后应用的JMH。

其中Eclipse collection的put土最好的土办法的返回值是void,与这种 集合不一样,什么都有有只有单独为它写另4个 测试土最好的土办法。

7273 import com.carrotsearch.hppc.LongLongHashMap

56}

910object HashMapBenchmark {

有以后,我们利用特质不能混入的形态,在生成HashMap的完后 ,混入LongLongOp,有以后交由testSetTraverse执行。从前我们每次只时要新建HashMap即可了。之类 ,FastUtil的测试如下:

Eclipse Collections: 由高盛开发的集合库,以后 捐给了eclipse基金会,成为了eclipse的项目.

BenchmarkMode,Benchmark的模式是测试吞吐率。

7950 @Benchmark

原文发布时间为: 2018-11-07

本文作者:Kirito的技术分享

本文来自云栖社区商务媒体合作伙伴“Kirito的技术分享”,了解相关信息不能关注“Kirito的技术分享”。

运行的过程中,Koloboke报另4个 诡异的空指针错误,什么都有有这么 通过测试;FastUtils在这种 量级好像有点儿慢,不乐意等什么都有有最终这么 把它加入测试。最终我们得到如下的结果列表:

OutputTimeUnit表示输出Benchmark结果的完后 ,计时单位是TimeUnit.SECONDS

1617 def get(key: Long): Long