Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precompute hashCode for value-based classes?

Tags:

java

hashcode

Value-based classes have the property that they

are final and immutable (though may contain references to mutable objects).

Consequently, if you know that your object only contains immutable instances, you could precompute the hashCode of the instance. This could speed up access when using Map or Set operations.

Looking at the implementation of hashCode from Instant, which is a value-based class, why have the developers decided against this pattern? Would the loss of performance for precomputing the hashCode be more significant than computing it over and over again when required?

// copied from Instant#hashCode
@Override
public int hashCode() {
    return ((int) (seconds ^ (seconds >>> 32))) + 51 * nanos;
}

So, under what condition is precomputing the hashCode justified?

like image 720
Glains Avatar asked Nov 12 '19 21:11

Glains


People also ask

What is the best strategy to calculate hashCode?

The easiest way to compute a field's hash code is to just call `hashCode` on it. Combining them could be done manually.

Why is 31 used in hashCode?

The value 31 was chosen because it is an odd prime. If it were even and the multiplication overflowed, information would be lost, as multiplication by 2 is equivalent to shifting. The advantage of using a prime is less clear, but it is traditional.

Where hashCode method is implemented?

Java equals() and hashCode() methods are present in Object class. So every java class gets the default implementation of equals() and hashCode().

What is a value based class?

Value-based classes, as defined in the Java docs, are classes which conform to a set of rules: - are final and immutable (though may contain references to mutable objects);


1 Answers

There isn't straight-forward reason why Instant doesn't cache hashcode. But some that I could think of:

Caching hashcode comes at a price: the instance variable declared:

  • It of-course occupies more memory per object. It may be alright to re-compute the hashcode, than allocate extra memory for every instance object
  • Worry about serialization/deserialization, as the instance variable would need to be preserved. Increasing the size of the serialized object
  • The internal implementation becomes difficult to be modified in future versions. Especially more so because of past serialized objects. Preserving backward compatibility becomes difficult for past version objects. Extra maintenance.
  • hashcode may never be called on an Instant object. In such a case, we waste CPU in computing something that is never used

So may not make sense to cache. May be it makes sense for String as it is so commonly used throughout. May be worth the headache.

like image 75
Jatin Avatar answered Oct 18 '22 22:10

Jatin