性能:Java的String.format

可能重复:
如果性能很重要,我应该使用Java的String.format()吗?

我想知道在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 

因此,如果我的测试有效, StringBuilderString.format更快。 好。 现在,我开始思考String.format工作原理。 它是一个简单的字符串连接,如"test " + i

StringBuilder连接和String.format之间有什么区别? 有没有像String.format一样简单的方法,像StringBuilder一样快?

我写了一个快速卡尺基准来比较String.format()StringBuilderStringBuffer ,普通String +运算符, String.replace()String.concat()方法:

 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()); } } 

结果如下(Java 1.6.0_26-b03,Ubuntu,32位):

caliper2

显然String.format()要慢得多(按一个数量级)。 StringBuffer也比StringBuilder慢得多(正如我们所教导的那样)。 最后, StringBuilderString +运算符几乎完全相同,因为它们编译为非常相似的字节码。 String.concat()有点慢。

如果简单连接就足够了,也不要使用String.replace()

String.format相对较慢,但通常不够快。

如果更简单,我会使用格式,除非您在分析应用程序时看到性能问题。

注意:示例中的String.format需要大约24微秒,并且还没有完全预热。 我会忽略前10K迭代。

恕我直言"test " + i在这种情况下是最简单的。

我已经运行了一个测试后的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; } }