Performance: Java's String.format [duplicate]

≡放荡痞女 提交于 2019-12-20 18:33:46

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!