How to Juice your Java Performance
In my previous post about equals and hashcode I thought I'd point out how to redesign the class in question to make better use of performance. If you have a situation where you create groups of objects that are immutable, but you need to pass them around in hashsets and/or look things up, a way to increase performance is to change from something like the following:
package blog.mainguy;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class LookupEntity {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object other) {
if (other != null && other instanceof LookupEntity) {
return new EqualsBuilder().append(this.getName(), ((LookupEntity) other).getName()).isEquals();
} else {
return false;
}
}
@Override
public int hashCode() {
return new HashCodeBuilder(17,31).append(this.getName()).hashCode();
}
}
to something like
package blog.mainguy;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
public class LookupEntity {
private String name;
private LookupEntity() {
}
public LookupEntity(String name) {
this.name = name == null?"":name;
hashCode = name.hashCode();
}
public String getName() {
return name;
}
private int hashCode;
@Override
public boolean equals(Object other) {
if (other != null && other instanceof LookupEntity) {
return this.name.equals(((LookupEntity)other).getName())
}
}
@Override
public int hashCode() {
return hashCode;
}
}
Note, I have not profiled this, it is based on my perception and understanding of how java works. It is also (as I noted) a pre-optimization that I personally wouldn't necessarily start with (though in many cases I might).
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Thomas Eichberger replied on Sun, 2012/06/10 - 1:55am
Peter Hendriks replied on Sun, 2012/06/10 - 6:36am
The first example is obviously verbose, commons features are not necessary at all.
The second example is still verbose, because Strings in Java cache their own hashcode already. Just returning name.hashCode(); in the hashCode function should be sufficient.
I would add the optimization to make name a final member. That will make it more clear that is intended as an immutable value, and helps in certain JIT optimizations too.
Mladen Girazovski replied on Sun, 2012/06/10 - 10:20am
Well, in that case, you have not optimized anything or improved performance.
All you have done is changing code based on assumptions, you actually don't know if you have improved performance or made it even worse or ifit had an measurable impact at all.
Robert Saulnier replied on Mon, 2012/06/11 - 8:44am
Greg Allen replied on Thu, 2012/06/14 - 9:07am
instead of
other != null && other instanceof LookupEntity
just use
other instanceof LookupEntity
Also worth mentioning the cost of this "optimisation" - namely at least 4 extra bytes per instance.