Found this out benchmarking an app at work. We’re pulling a fair amount of data from the database via hibernate, and hydrating those objects into a set of domain objects. It’s a pretty straight-forward set of domain objects, involving stores, ownership information, operation information (store hours, addresses, etc). The pulling of data was terribly slow, though.
Putting the app through it’s paces in YourKit, however, revealed something we didn’t expect: the hashcode generation for a number of our domain objects was dominating the list of hotspots. In particular, NullObject#is.call(….) was taking an inordinate amount of our cpu time.
Now, our data can have a good number of null values; not every field is populated … and that appears to be the crux of the problem.
I took one of the prime culprits from our domain and wrote a quick unit test just to run over a large number of objects and generate hashcodes, and output how long it takes. I also generated a set of hashcode/equals method via Eclipse … and hand-generated the same same via Apache’s EqualsBuilder and HashCodeBuilder, as well a Guava’s Objects utility (and for good measure, Java 7’s equivalent Objects utility).
What I’m seeing in 10M hashcode generations is roughly like this:
Groovy Time: 44001 ms Eclipse Time: 4488 ms Apache Time: 4361 ms Guava Time: 5912 ms 7 Time: 5919 ms
Clearly, if you’re going to have null attributes, then it’s worth the time to produce your own equals and hashcode methods; with the clean appearance of the Apache utility methods, I’m definitely leaning that direction.