性能:Java的String.format

时间:2012-10-08 17:51:29

标签: java performance string-concatenation

  

可能重复:
  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

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

StringBuilder连接和String.format之间的区别是什么?有一种简单的方式String.format和快速的StringBuilder吗?

3 个答案:

答案 0 :(得分:38)

我写了一个快速caliper基准来比较String.format()StringBuilderStringBuffer,普通String +运营商,{{1 }和String.replace()方法:

String.concat()

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

caliper2

显然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慢得多(正如我们所教导的那样)。最后,StringBuilderStringBuilder 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;
    }
}