In Java, what would the fastest way to iterate over all the chars in a String, this:
String str = "a really, really long string";
for (int i = 0, n = str.length(); i < n; i++) {
char c = str.charAt(i);
}
Or this:
char[] chars = str.toCharArray();
for (int i = 0, n = chars.length; i < n; i++) {
char c = chars[i];
}
EDIT :
What I'd like to know is if the cost of repeatedly calling the charAt
method during a long iteration ends up being either less than or greater than the cost of performing a single call to toCharArray
at the beginning and then directly accessing the array during the iteration.
It'd be great if someone could provide a robust benchmark for different string lengths, having in mind JIT warm-up time, JVM start-up time, etc. and not just the difference between two calls to System.currentTimeMillis()
.
Looks like niether is faster or slower
For long strings I'll chose the first one. Why copy around long strings? Documentations says:
//Edit 1
I've changed the test to trick JIT optimisation.
//Edit 2
Repeat test 10 times to let JVM warm up.
//Edit 3
Conclusions:
First of all
str.toCharArray();
copies entire string in memory. It can be memory consuming for long strings. MethodString.charAt( )
looks up char in char array inside String class checking index before. It looks like for short enough Strings first method (i.e.chatAt
method) is a bit slower due to this index check. But if the String is long enough, copying whole char array gets slower, and the first method is faster. The longer the string is, the slowertoCharArray
performs. Try to change limit infor(int j = 0; j < 10000; j++)
loop to see it. If we let JVM warm up code runs faster, but proportions are the same.After all it's just micro-optimisation.
The second one causes a new char array to be created, and all chars from the String to be copied to this new char array, so I would guess that the first one is faster (and less memory-hungry).
This is just micro-optimisation that you shouldn't worry about.
returns you a copy of
str
character arrays (in JDK, it returns a copy of characters by callingSystem.arrayCopy
).Other than that,
str.charAt()
only checks if the index is indeed in bounds and returns a character within the array index.The first one doesn't create additional memory in JVM.
Despite @Saint Hill's answer if you consider the time complexity of str.toCharArray(),
the first one is faster even for very large strings. You can run the code below to see it for yourself.
output:
Just for curiosity and to compare with Saint Hill's answer.
If you need to process heavy data you should not use JVM in client mode. Client mode is not made for optimizations.
Let's compare results of @Saint Hill benchmarks using a JVM in Client mode and Server mode.
See also: Real differences between "java -server" and "java -client"?
CLIENT MODE:
SERVER MODE:
CONCLUSION:
As you can see, server mode is much faster.
String.toCharArray()
creates new char array, means allocation of memory of string length, then copies original char array of string usingSystem.arraycopy()
and then returns this copy to caller. String.charAt() returns character at positioni
from original copy, that's whyString.charAt()
will be faster thanString.toCharArray()
. Although,String.toCharArray()
returns copy and not char from original String array, whereString.charAt()
returns character from original char array. Code below returns value at the specified index of this string.code below returns a newly allocated character array whose length is the length of this string