Optimise ObjectsHashIterative hash function.
Avoid using Arrays.deepHashCode. The array passed to deepHashCode is always length 2. So we can unroll the same computation for the fixed 2 iterations.
This commit is contained in:
parent
a699c8b9ba
commit
d6eeceb018
|
@ -60,7 +60,14 @@ public final class ObjectsHashIterative implements HashFunction {
|
||||||
if (seed == 0) {
|
if (seed == 0) {
|
||||||
last = 0;
|
last = 0;
|
||||||
}
|
}
|
||||||
final long result = Arrays.deepHashCode(new Object[] { last, buffer });
|
// Effectively:
|
||||||
|
// result = Arrays.deepHashCode(new Object[] { last, buffer });
|
||||||
|
// The method loops over items starting with result=1
|
||||||
|
// for i in items:
|
||||||
|
// result = 31 * result + hashCode(i)
|
||||||
|
// Here we unroll the computation to 2 iterations.
|
||||||
|
// The computation is done using 32-bit integers then cast to a long
|
||||||
|
final long result = 31 * (31 + Long.hashCode(last)) + Arrays.hashCode(buffer);
|
||||||
last += result;
|
last += result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,11 @@ public class ObjectsHashIterativeTest extends AbstractHashFunctionTest {
|
||||||
long l = obj.apply(buffer, 0);
|
long l = obj.apply(buffer, 0);
|
||||||
long prev = 0;
|
long prev = 0;
|
||||||
assertEquals(Arrays.deepHashCode(new Object[] {prev, buffer}), l);
|
assertEquals(Arrays.deepHashCode(new Object[] {prev, buffer}), l);
|
||||||
prev += l;
|
for (int i = 1; i <= 5; i++) {
|
||||||
l = obj.apply(buffer, 1);
|
prev += l;
|
||||||
assertEquals(Arrays.deepHashCode(new Object[] {prev, buffer}), l);
|
l = obj.apply(buffer, i);
|
||||||
prev += l;
|
assertEquals(Arrays.deepHashCode(new Object[] {prev, buffer}), l);
|
||||||
l = obj.apply(buffer, 2);
|
}
|
||||||
assertEquals(Arrays.deepHashCode(new Object[] {prev, buffer}), l);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue