这是一个奇怪的案例,最近出现在分析我一直在研究的专门收藏品时。
该集合几乎只是两个数组,一个是int[]
个数组,另一个是Object[]
数组,其哈希函数提供快速查找。这一切都运行良好,但我来分析代码并得到一些奇怪的结果;对于剖析,我决定采用老式的方式,抓住System.currentTimeMillis()
,反复运行测试,然后检查已经过了多长时间,如下所示:
long sTime = System.currentTimeMillis();
for (int index : indices)
foo.remove(index);
long took = System.currentTimeMillis() - sTime;
在我的测试中,我foo
准备了200,000个条目,并预先生成了我将删除的indices
列表。我使用循环重置并运行测试一千次,并将took
添加到正在运行的总计中。
现在,对于命令,与其他数据类型相比,我获得了非常好的结果,除了我的remove(int)
方法。但是,我一直在努力找出原因,因为我的删除方法与我的get(int)
方法相同(显然除了删除),如下所示:
public Object get(int key) {
int i = getIndex(key); // Hashes key and locates it
return (i >= 0) ? this.values[i] : null;
}
public Object remove(int key) {
int i = getIndex(key); // Does exactly the same as above
if (i >= 0) {
--this.size;
++this.modifications; // For concurrent access behaviour
this.keys[i] = 0; // Zero indicates null entry
Object old = this.values[i];
this.values[i] = null;
return old;
}
return null;
}
虽然我希望删除时间稍长一些,但执行时间为get(int)
的时间超过5倍。但是,如果我注释掉this.keys[i] = 0
行,那么效果几乎与get(int)
相同。
我是否正确地指出这是一个为我的int[]
数组赋值的问题?我已尝试对所有this.values
操作进行评论并遇到相同的慢速时间,但在this.values
注释this.keys[i] = 0
时始终一致地解决问题;我完全不知道发生了什么,有什么事要做吗?
考虑到删除相对较少,性能仍然很好,但设置int[]
中的值似乎具有如此大的影响似乎很奇怪,所以我很想知道原因。
答案 0 :(得分:-1)
写入的代码不能同时工作。如果没有显示其他并发代码,那很可能是源时序差异。除此之外,最可能的原因是除了值[]数组更改内存访问模式之外,仅仅访问keys []数组。例如,从寄存器切换到存储器位置,L1高速缓存切换到L2高速缓存,或L3高速缓存或主存储器。 “虚假共享”是退化模式的一个例子。 “机械同情”是用于调整当前硬件架构的名称。