Comparison of equals, equalsIgnoreCase and compareTo String methods

Quite a few developers seem to use the compareTo() method to compare Strings, which is a bit odd because the purpose of this method is to provide an ordering (i.e. Comparable interface) rather than testing for equality. Likely they have been taught to do String comparisons that way and have become accustomed with that method. However, unlike the equals() method, compareTo() will throw a NullPointerException if its argument is a null object. For instance:

"a".compareTo((String)null); // Throws java.lang.NullPointerException
"a".equals((String)null); // Returns false

Also many developers seem to be using equalsIgnoreCase() as their default String comparison method. Even in cases where the 2 strings will always be in the same case, or where the string values are always numeric values such as “1”, “312”, etc.

Aside from their original intend, let’s see how these 3 String methods compare in performance. The following little program executes each of these compare methods 1 billion times each, and then displays how long each test took.

import java.util.Date;
public class StringTest {
    public static void main(String[] args) {
        String s1 = new String("value1");
        String s2 = new String("value1");
        long t1 = (new Date()).getTime();
        for (long i = 0; i < 1000000000; i++) {
            s2.equals(s1);
        }
        long t2 = (new Date()).getTime();
        for (long i = 0; i < 1000000000; i++) {
            s2.equalsIgnoreCase(s1);
        }
        long t3 = (new Date()).getTime();
        for (long i = 0; i < 1000000000; i++) {
            s2.compareTo(s1);
        }
        long t4 = (new Date()).getTime();
        System.out.println("equals() test: " + (t2-t1) + " ms");
        System.out.println("equalsIgnoreCase() test: " + (t3-t2) + " ms");
        System.out.println("compareTo() test: " + (t4-t3) + " ms");
    }
}

This is the result:

equals() test: 498 ms
equalsIgnoreCase() test: 27073 ms
compareTo() test: 475 ms

So it is obvious that equalsIgnoreCase() is by far the worst performer, which is to be expected since this includes the additional step of converting 2 strings to the same case before comparing them. However, compareTo() seems to consistently perform slightly better than equals(). Now, the difference of 23 milliseconds is probably negligible, especially taken into account that the above test used 1 billion iterations for each method test, but it’s still an interesting fact.

2 thoughts on “Comparison of equals, equalsIgnoreCase and compareTo String methods

  1. I agree that equalsIgnoreCase() should be used very judiciously. However I think you’re mistaken about compareTo() being faster – that’s most likely just an artifact of the fact that you test it last, and the JVM has had more time to warm up. Try testing them in the reverse order, and you will see different results. At least, I did. They’re effectively the same amount of time to execute, I think.

    But wait! Those methods aren’t really equivalent. The result of compareTo() needs to be compared to 0 in order to convert it into a boolean and do anything useful with the result, like make a decision in an if statement or loop. So you should really compare “x.equals(y)” against “compareTo(y) == 0” to make the result meaningful Do that, and I think you will see equals() is the clear winner.

Leave a Reply

Your email address will not be published. Required fields are marked *

*