可能重复:
Should I use Java's String.format() if performance is important?
我想知道在Java应用程序中使用String.format
而不是StringBuilder
是否合适...所以,我只是写一个简单的测试,如下所示:
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);
}
结果在哪里:
238
15
因此,如果我的测试有效,则StringBuilder
比String.format
快。好。
现在,我开始思考String.format
是如何工作的。它是一个简单的字符串连接,如"test " + i
?
StringBuilder
连接和String.format
之间的区别是什么?有一种简单的方式String.format
和快速的StringBuilder
吗?
答案 0 :(得分:38)
我写了一个快速caliper基准来比较String.format()
与StringBuilder
,StringBuffer
,普通String
+
运营商,{{1 }和String.replace()
方法:
String.concat()
结果如下(Java 1.6.0_26-b03,Ubuntu,32位):
显然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());
}
}
要慢得多(按一个数量级)。同样String.format()
比StringBuffer
慢得多(正如我们所教导的那样)。最后,StringBuilder
和StringBuilder
String
运算符几乎相同,因为它们编译为非常相似的字节码。 +
有点慢。
如果简单连接就足够了,也不要使用String.concat()
。
答案 1 :(得分:3)
String.format相对较慢但通常速度足够快。
如果更简单,我会使用格式,除非您在分析应用程序时看到性能问题。
注意:示例中的String.format需要大约24微秒,并且还没有完全预热。我会忽略前10K迭代。
在这种情况下,恕我直言"test " + i
是最简单的。
答案 2 :(得分:1)
我已经运行了一个测试后的JVM预热(一旦编译了方法)并获得了类似的结果,StringBuilder的速度提高了30倍以上。
格式: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;
}
}