16

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

我想知道是否可以String.format在 Java 应用程序中使用而不是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

4

3 回答 3

38

我写了一个快速卡尺基准来比较String.format()StringBuilder, StringBuffer,正常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 位):

卡尺2

显然String.format()要慢得多(一个数量级)。也StringBufferStringBuilder(我们被教导的)慢得多。finallyStringBuilderString +operator 几乎相同,因为它们编译为非常相似的字节码。String.concat()有点慢。

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

于 2012-10-08T18:05:53.567 回答
3

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

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

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

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

于 2012-10-08T17:53:54.590 回答
1

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;
    }
}
于 2012-10-08T18:00:14.500 回答