Performance Zone is brought to you in partnership with:

I have a passion for talking to people, identifying problems, and writing software. When I'm doing my job correctly, software is easy to use, easy to understand, and easy to write... in that order. Michael is a DZone MVB and is not an employee of DZone and has posted 52 posts at DZone. You can read more from them at their website. View Full User Profile

How to Juice your Java Performance

06.09.2012
| 8800 views |
  • submit to reddit

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).

Published at DZone with permission of Michael Mainguy, author and DZone MVB. (source)

(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

This is quite an old idea.

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

Note, I have not profiled this, it is based on my perception and understanding of how java works. 

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

In the 2nd equals method, you forgot the else return false.

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.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.