Possible Duplicate:
Should I use Java's String.format() if performance is important?
I was wondering if is good to use String.format
in Java apps instead of StringBuilder
... so, I just write a simple test, like this:
public static void main(String[] args) {
int i = 0;
Long start = System.currentTimeMillis();
while (i < 10000) {
String s = String.format("test %d", i);
i++;
}
System.out.println(System.currentTimeMillis() - start);
i = 0;
start = System.currentTimeMillis();
while (i < 10000) {
String s = new StringBuilder().append("test ").append(i).toString();
i++;
}
System.out.println(System.currentTimeMillis() - start);
}
And the results where:
238
15
So, if my test is valid, StringBuilder
is faster than String.format
. OK.
Now, I start thinking how String.format
works. Is it a simple String concatenation, like "test " + i
?
What the differences between StringBuilder
concatenation and String.format
? Is there a way simple as String.format
and fast like StringBuilder
?
Put another way, using StringBuilder here is over 40 TIMES faster than String. format() . This is probably quite a bit bigger difference than most Java developers would have guessed.
Abstract: One of the most convenient ways of constructing complex Strings is with String. format(). It used to be excessively slow, but in Java 17 is about 3x faster.
Generally you should use String. Format because it's relatively fast and it supports globalization (assuming you're actually trying to write something that is read by the user).
Format (using Reflector) and it actually creates a StringBuilder then calls AppendFormat on it. So it is quicker than concat for multiple stirngs. Quickest (I believe) would be creating a StringBuilder and doing the calls to Append manually.
I wrote a quick caliper benchmark to compare String.format()
vs. StringBuilder
, StringBuffer
, normal String
+
operator, String.replace()
and String.concat()
methods:
public class StringFormatBenchmark extends SimpleBenchmark {
public void timeStringFormat(int reps) {
while (--reps >= 0) {
String s = String.format("test %d", reps);
}
}
public void timeStringBuilder(int reps) {
while (--reps >= 0) {
String s = new StringBuilder("test ").append(reps).toString();
}
}
public void timeStringBuffer(int reps) {
while (--reps >= 0) {
String s = new StringBuffer("test ").append(reps).toString();
}
}
public void timeStringPlusOperator(int reps) {
while (--reps >= 0) {
String s = "test " + reps;
}
}
public void timeReplace(int reps) {
while (--reps >= 0) {
String s = "test {}".replace("{}", String.valueOf(reps));
}
}
public void timeStringConcat(int reps) {
while (--reps >= 0) {
String s = "test ".concat(String.valueOf(reps));
}
}
public static void main(String[] args) {
new Runner().run(StringFormatBenchmark.class.getName());
}
}
The results follow (Java 1.6.0_26-b03, Ubuntu, 32 bits):
Clearly String.format()
is much slower (by an order of magnitude). Also StringBuffer
is considerably slower than StringBuilder
(as we were taught). Finally StringBuilder
and String
+
operator are almost identical since they compile to very similar bytecode. String.concat()
is a bit slower.
Also don't use String.replace()
if simple concatenation is sufficient.
String.format is relatively slower but usually more than fast enough.
I would use format if that is simpler, unless you can see a performance issue when you profile your application.
Note: The String.format in your example is taking ~24 micro-seconds and won't be fully warmed up yet. I would ignore the first 10K iterations.
IMHO "test " + i
is the simplest in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With