java hashmap性能_Java 8 中 HashMap 的性能提升

HashMap是一个高效通用的数据结构,它在每一个Java程序中都随处可见。先来介绍些基础知识。你可能也知 道,HashMap使用key的hashCode()和equals()方法来将值划分到不同的桶里。桶的数量通常要比map中的记录的数量要稍大,这样 每个桶包括的值会比较少(最好是一个)。当通过key进行查找时,我们可以在常数时间内迅速定位到某个桶(使用hashCode()对桶的数量进行取模) 以及要找的对象。

这些东西你应该都已经知道了。你可能还知道哈希碰撞会对hashMap的性能带来灾难性的影响。如果多个hashCode()的值落到同一个桶内的 时候,这些值是存储到一个链表中的。最坏的情况下,所有的key都映射到同一个桶中,这样hashmap就退化成了一个链表——查找时间从O(1)到 O(n)。我们先来测试下正常情况下hashmap在Java 7和Java 8中的表现。为了能完成控制hashCode()方法的行为,我们定义了如下的一个Key类:

class Key implements Comparable {

private final int value;

Key(int value) {

this.value = value;

}

@Override

public int compareTo(Key o) {

return Integer.compare(this.value, o.value);

}

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass())

return false;

Key key = (Key) o;

return value == key.value;

}

@Override

public int hashCode() {

return value;

}

}

Key类的实现中规中矩:它重写了equals()方法并且提供了一个还算过得去的hashCode()方法。为了避免过度的GC,我将不可变的Key对象缓存了起来,而不是每次都重新开始创建一遍:

class Key implements Comparable {

public class Keys {

public static final int MAX_KEY = 10_000_000;

private static final Key[] KEYS_CACHE = new Key[MAX_KEY];

static {

for (int i = 0; i < MAX_KEY; ++i) {

KEYS_CACHE[i] = new Key(i);

}

}

public static Key of(int value) {

return KEYS_CACHE[value];

}

}

现在我们可以开始进行测试了。我们的基准测试使用连续的Key值来创建了不同的大小的HashMap(10的乘方,从1到1百万)。在测试中我们还会使用key来进行查找,并测量不同大小的HashMap所花费的时间:

import com.google.caliper.Param;

import com.google.caliper.Runner;

import com.google.caliper.SimpleBenchmark;

public class MapBenchmark extends SimpleBenchmark {

private HashMap map;

@Param

private int mapSize;

@Override

protected void setUp() throws Exception {

map = new HashMap<>(mapSize);

for (int i = 0; i < mapSize; ++i) {

map.put(Keys.of(i), i);

}

}

public void timeMapGet(int reps) {

for (int i = 0; i < reps; i++) {

map.get(Keys.of(i % mapSize));

}

}

}

c3b30e890d6117e06923cb89855cf45e.png

0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值