HashMap collision speed (regression 7->8)
Peter Levart
peter.levart at gmail.com
Mon Jan 12 08:26:36 UTC 2015
On 01/12/2015 12:26 AM, Peter Levart wrote:
> With tree bins we don't need heavy bit-smearing to get decent
> performance in speed, but the table gets quite sparse anyway (although
> this is the smaller of the space overheads - tree nodes are bigger).
> For example, for 1M integral Floats, we get the following:
>
> >>> Float ...
> Capacity: 2097152
> Load factor: 0.75
> Size: 1000000
> Bin sizes: 0*1966080 1*0 2*0 3*24288 4*41248 5*0 6*0
> 7*0 8*0 9*0 10*4456 11*22963 12*30554 13*7539 14*24 total=1000000
> Empty bins: 93.8 %
> Unique hash codes per bin: 0*1966080 1*0 2*0 3*24288 4*41248 5*0 6*0
> 7*0 8*0 9*0 10*4456 11*22963 12*30554 13*7539 14*24 total=1000000
Hi Doug,
Did bit smearing function used in JDK 7 have negative impact on any
hashCodes or was it replaced with simpler one just because it is not
needed when tree bins are used?
At least on my i7 PC the old bit smearing compared to new one does not
show that much difference in relative speed (jdk7's is about 20% slower)
while absolute time is in range of a few ns:
Benchmark Mode Samples Score Error Units
j.t.HashSmearingTest.testHash7 avgt 60 3.472 ± 0.105 ns/op
j.t.HashSmearingTest.testHash8 avgt 60 2.881 ± 0.087 ns/op
Using the following JMH benchmark:
@State(Scope.Thread)
@Fork(6)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 7)
@Measurement(iterations = 10)
public class HashSmearingTest {
static int hash7(Object key) {
if (key == null) return 0;
int h = key.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
static int hash8(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
private int cnt = ThreadLocalRandom.current().nextInt();
@Benchmark
public int testHash7() {
return hash7(cnt++);
}
@Benchmark
public int testHash8() {
return hash8(cnt++);
}
}
Regards, Peter
More information about the core-libs-dev
mailing list