问题
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
?
回答1:
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.
回答2:
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.
回答3:
I have run a test post-JVM warmup (once the methods are compiled) and get similar results, with StringBuilder more than 30x quicker.
format: 943
stringbuilder: 26
public class TestPerf {
private static int NUM_RUN;
public static void main(String[] args) {
NUM_RUN = 100_000;
//warm up
for (int i = 0; i < 10; i++) {
method1();
method2();
}
System.gc();
System.out.println("Starting");
long sum = 0;
long start = System.nanoTime();
for (int i = 0; i < 10; i++) {
sum += method1();
}
long end = System.nanoTime();
System.out.println("format: " + (end - start) / 1000000);
System.gc();
start = System.nanoTime();
for (int i = 0; i < 10; i++) {
sum += method2();
}
end = System.nanoTime();
System.out.println("stringbuilder: " + (end - start) / 1000000);
System.out.println(sum);
}
private static int method1() {
int sum = 0;
for (int i = 0; i < NUM_RUN; i++) {
String s = String.format("test %d", i);
sum += s.length();
}
return sum;
}
private static int method2() {
int sum = 0;
for (int i = 0; i < NUM_RUN; i++) {
String s = new StringBuilder().append("test ").append(i).toString();
sum += s.length();
}
return sum;
}
}
来源:https://stackoverflow.com/questions/12786902/performance-javas-string-format