tags:

views:

213

answers:

5

What's the quickest to compare two strings in Java?

Is there something faster than equals?

EDIT: I can not help much to clarify the problem.

I have two String which are sorted alphabetically and EXACTLY the same size

Example: abbcee and abcdee

Strings can be long up to 30 characters

+9  A: 

I don't expect that Sun Oracle hasn't already optimized the standard String#equals() to the max. So, I expect it to be already the quickest way. Peek a bit round in its source if you want to learn how they implemented it. Here's an extract:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                    return false;
            }
            return true;
        }
    }
    return false;
}
BalusC
Just curious, is that a real parrot on your hat?
NullUserException
@Null: Yes, it's a genuine [Amazon Parrot](http://en.wikipedia.org/wiki/Amazon_parrot). He was just about 3 months old (young) there at the picture. He's somewhat larger right now. His name is Chichiray. A very cool bird :)
BalusC
Pretty interesting.
org.life.java
@org: The parrot or my answer? :)
BalusC
Chichiray ....... :)
org.life.java
1 + for posting code of equals
org.life.java
This looks pretty optimized to me.... it would be theoretically possible to optimize it further for the OP's specific constraints (e.g. using the knowledge that the strings are already of equal length, and higher likelihood of different characters in the middle of the string), but you obviously can't do that in practice because the class is final and the fields are private .... +1 for digging out the source!
mikera
A: 

Some options to test:

Freiheit
+1  A: 

It depends what you need. I think equals() is really optimized but perhaps you need something else faster than equals(). Take a look at this post.

oyo
A: 

As always, you will need to benchmark for your application / environment. And unless you have already profiled and idetified this as a performance bottleneck, it's probably not going to matter ("premature optimization is the root of all evil").

Having said that:

a.equals(b) is really fast for Strings. It's probably one of the most tightly optimized pieces of code in the Java platform. I'd be very surprised if you can find any faster way of comparing two arbitrary strings.

There are special cases where you can cheat and use (a==b) safely, e.g. if you know that both Strings are interned (and therefore value identity implies object identity). In that case it may be slightly faster than a.equals(b) - but again this depends on compiler/JVM implementation. And it's very easy to shoot yourself in the foot if you don't know what you are doing.....

mikera
p.s. I have just micro-benchmarked this, and (a==b) does beat a.equals(b) by a factor of about 2-4 times (30ns vs. 70-110ns) in my environment (Eclipse on Sun Java 1.6). YMMV, and usual caveats about micro-benchmarking do of course apply :-)
mikera
Looking at the implementation code posted by @BalusC, I can see absolutely no heavy optimizations, nothing at all to warrant your statement. Granted, optimizing this already trivial code isn’t easy. But low-level, what *could* have been done to optimize is to move from char-wise to int-wise comparison (obviously this requires low-level tricks not readily available in Java, and it might not be faster after all).
Konrad Rudolph
Hmmm It looks extremely tightly optimized to me, to the extent that e.g. they are re-using the string length as a negative loop counter (which is a classic low-level optimization). I can't see personally see any additional optimization that could be made, short of abandoning pure Java and dropping to a specialized native implementation (and it's possible that the JIT does this anyway....)
mikera
+1  A: 

If you can show that it's a significant bottleneck, which would surprise me, you could try

s1.hashCode() == s2.hashCode() && s1.equals(s2)

It might be a bit faster. It mightn't.

EJP
This was my first idea, too. Since string are immutual (is this really spelled right?) you're basically comparing constant ints here, which should be fast. Could be a problem only if the objects are equal most of the time, you could dynamically swap the implementation then. Too sad I don't have the jdk on this machine, would love to profile that now.
atamanroman
it's "immutable" :)
KevinDTimm