Notinlist
Notinlist

Reputation: 16650

Fastest char to string conversion in Java

I see four alternatives for converting a char to a Stirng in Java.

v = Something.lookup(new String((char)binaryData[idx])); // SORRY! Wrong.
v = Something.lookup("" + (char)binaryData[idx]);
v = Something.lookup(String.valueOf((char)binaryData[idx]));
v = Something.lookup(Character.toString((char)binaryData[idx])));

I think that the first is the slowest. The second is very convenient. I speculate that the third may return a previously created String instance, but I'm not sure, and the API documentation does not say so. The same applies to option four. This reusing of instance would be very fortunate because then a hash based lookup could take advantage of hashCode() caching in String. (Which feature is also not described in the API documentation, but many people told me.)

I'm coming from C++ and I feel this lack of complexity informations disturbing. :-) Are my speculations correct? Do we have any kind of official documentation where performance guaranties and the caching mechanisms declared?

Upvotes: 7

Views: 3558

Answers (4)

biziclop
biziclop

Reputation: 49804

I'm coming from C++ and I feel this lack of complexity informations disturbing. :-) Are my speculations correct? Do we have any kind of official documentation where performance guaranties and the caching mechanisms declared?

To answer this part of the question: in general there isn't. You will find information on the asymptotic performance of built-in collections and maybe a couple of other areas but by and large these issues were left to the VM implementations' discretion. You can of course always look at the source code but bear in mind that there are things that affect performance which you have no direct control over: JIT compiling and garbage collection are the two biggest.

Should you be disturbed by this? I don't think so, Java operates on the premise that low-level performance is rarely an issue the application developer needs to concern herself or himself with. It's a trade-off and you can argue whether it's a good trade-off or not but it is what it is.

But by the time you get to the point where you can develop really high performance systems, you'll have picked up all the necessary information along the way.

Upvotes: 1

Davide Lorenzo MARINO
Davide Lorenzo MARINO

Reputation: 26946

The first solution doesn't compile. The second solution internally creates a String calling a code similar to Character.valueOf(char). Third solution is better than fourth because internal implementation of Character.toString(char ch) is a call to String.valueOf

public static String toString(char c) {
    return String.valueOf(c);
}

Internal implementation of the third String.valueOf(char ch) is

public static String valueOf(char c) {
    char data[] = {c};
    return new String(0, 1, data);
}

Upvotes: 1

isnot2bad
isnot2bad

Reputation: 24464

First of all, the Java specification does not say anything about performance concerning these four methods, hence the results may vary depending on the JRE version and vendor you use.

If you use Oracle's JRE, you can easily inspect the source code by yourself! In Java 8, it is as follows:

Given a char c with some value:

  • new String(c) doesn't compile. No such constructor.
  • "" + c looks ugly, cumbersome and tricky. Internally it creates a new empty StringBuilder and appends the character to it. Then it creates a new String instance out of the StringBuilder.
  • Character.toString(c) delegates to String.valueOf(c).
  • String.valueOf(c) creates a new String instance.

So which one to use?

The most readable!

That's String.valueOf(c) or Character.toString(c) in my point of view!

Upvotes: 10

EvenLisle
EvenLisle

Reputation: 4812

The second one is certainly(in theory) slower, as it is translated into

v = Something.lookup(new StringBuilder().append("").append((char)binaryData[idx]).toString());

StringBuilders are implemented using a char[] initialized to hold 16 values. The StringBuilder option therefore initializes a char[] of size 16, only to copy the cells that are set (only the first one in this case) to the resulting string.

String.valueOf (which is equivalent to Character.toString) uses a char[] of size 1, and then directly sets the String's backing char[], thereby avoiding the need for a copy.

The first approach will not compile (at least not under java 7), as there is no String constructor accepting a single character as input: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

Upvotes: 2

Related Questions