Java/HashMap/Performance
下面是HashMap实现的Java/HashMap/Performance,java,performance,hashmap,Java,Performance,Hashmap,下面是HashMap实现的put()方法。对于100000个元素,它运行大约1500毫秒,而Collections的HashMap运行8毫秒 是什么让性能有如此巨大的差异? (我的哈希函数只是基于hashCode(),负载因子大约为0,6,因此它应该运行良好) public boolean put(K键,V值) { 如果(大小>上限*荷载系数)展开(); int i; 对于(i=hash(key);容器[i]!=null;i=(i+1)%cap) { if(容器[i].key.equals(ke
put()
方法。对于100000个元素,它运行大约1500毫秒,而Collections
的HashMap运行8毫秒
是什么让性能有如此巨大的差异?
(我的哈希函数只是基于hashCode(),负载因子大约为0,6,因此它应该运行良好)
public boolean put(K键,V值)
{
如果(大小>上限*荷载系数)展开();
int i;
对于(i=hash(key);容器[i]!=null;i=(i+1)%cap)
{
if(容器[i].key.equals(key))
{
容器[i]=新条目(键、值);
返回true;
}
}
容器[i]=新条目(键、值);
大小++;
返回true;
使用%
是一个非常昂贵的操作,事实上HashMap并没有全部使用它,也就是说,它的大小总是2的幂,允许掩码来完成这项工作。在您的情况下,单个操作可以多次调用%
,尤其是在负载系数不够高的情况下。
尝试删除%
注意:如果您像以前一样使用开放寻址,则需要降低负载因子,例如小于0.5。HashMap具有更高的负载因子,因为它以不同的方式处理冲突
还注意到
- 创建一个新的中等寿命对象是非常昂贵的,我会在更新值时避免这种情况
- 您可以缓存hashCode以加速expand(),这意味着您可以在执行equals()之前比较hashCode
%
是一个非常昂贵的操作,事实上HashMap并没有完全使用它,也就是说,它的大小始终是2的幂,以允许掩码来完成这项工作。在您的情况下,单个操作可以多次调用%
,尤其是在负载系数不够高的情况下。
尝试删除%
注意:如果您像以前一样使用开放寻址,则需要降低负载因子,例如小于0.5。HashMap具有更高的负载因子,因为它以不同的方式处理冲突
还注意到
- 创建一个新的中等寿命对象是非常昂贵的,我会在更新值时避免这种情况
- 您可以缓存hashCode以加速expand(),这意味着您可以在执行equals()之前比较hashCode
System.nanotime()
预热阶段:)您通常无法与JVM实现竞争。它们针对不同的类型、内存分配等进行了高度优化。一些容器直接与底层本机代码协同工作,而这是纯Java实现无法实现的。Tunaki是对的,有限数量的不可靠测试并不意味着任何不可靠的测试Thing如果您事先知道条目的数量,您可以设置初始容量。这并不能解决根本原因,但可能已经足够好了,因为您从未展开()您是如何测量这些数字的?如果您没有使用适当的基准工具,您可以将其从阳台上扔下。控制台和System.nanotime()
预热阶段:)您通常无法与JVM实现竞争。它们针对不同的类型、内存分配等进行了高度优化。一些容器直接与底层本机代码协同工作,而这是纯Java实现无法实现的。Tunaki是对的,有限数量的不可靠测试并不意味着任何不可靠的测试thing如果您事先知道条目数,您可以设置初始容量。这并不能解决根本原因,但可能已经足够好了,因为您从未展开过()关于%operator,您完全正确。我将其替换为I=(I<(cap-1))?i+1:0
性能提高到250毫秒。然后我稍微降低了加载因子,现在它运行35:)谢谢!您关于%operator的说法完全正确。我将其替换为i=(i
性能提高到250毫秒。然后我稍微降低了加载因子,现在它运行35:)谢谢!
public boolean put(K key, V value)
{
if (size > cap*LOAD_FACTOR) expand();
int i;
for(i=hash(key);container[i] != null;i=(i+1) % cap)
{
if(container[i].key.equals(key))
{
container[i] = new Entry<K,V>(key,value);
return true;
}
}
container[i] = new Entry<K,V>(key,value);
size++;
return true;