2

If I run this program the output is:

init: 1239.0
toCharArray: 1343.6
arraycopy: 1583.8

The first question is:
Why init() is faster than toCharArray()? Is there a compiler optimization here? (I am using Java 1.8.0_20)

The second question is:
Why toCharArray() is faster than arraycopy()? I copied arraycopy() from here: String.toCharArray().

public class MyClass {

    private static char[] SRC = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };

    public static void main(String[] args) {
        long start = 0;
        int init = 0, toCharArray = 0, arraycopy = 0;
        for (int j = 0; j < 5; j++) {
            start = System.currentTimeMillis();
            for (int i = 0; i < 100000000; i++)
                init();
            init += (System.currentTimeMillis() - start);

            start = System.currentTimeMillis();
            for (int i = 0; i < 100000000; i++)
                toCharArray();
            toCharArray += (System.currentTimeMillis() - start);

            start = System.currentTimeMillis();
            for (int i = 0; i < 100000000; i++)
                arraycopy();
            arraycopy += (System.currentTimeMillis() - start);
        }
        System.out.println("init: " + init / 5.0);
        System.out.println("toCharArray: " + toCharArray / 5.0);
        System.out.println("arraycopy: " + arraycopy / 5.0);
    }

    private static void init() {
        char[] c = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
        doSomething(c);
    }

    private static void toCharArray() {
        char[] c = "abcdefg".toCharArray();
        doSomething(c);
    }

    private static void arraycopy() {
        char[] c = new char[SRC.length];
        System.arraycopy(SRC, 0, c, 0, SRC.length);
        doSomething(c);
    }

    private static void doSomething(char[] c) {
        for (int i = 0; i < c.length; i++)
            c[i] = ' ';
    }

}

EDIT

Caliper result:

init:        min=11.90, 1st qu.=12.27, median=12.48, mean=12.44, 3rd qu.=12.54, max=13.16
toCharArray: min=13.10, 1st qu.=13.21, median=13.39, mean=13.49, 3rd qu.=13.78, max=14.27
arraycopy:   min=15.42, 1st qu.=15.49, median=15.51, mean=15.51, 3rd qu.=15.55, max=15.58
3
  • 6
    These results can be ignored as you haven't warmed the JVM. Either learn how to microbench Java or use a testing library like Caliper. Commented Sep 19, 2014 at 22:49
  • Yup, test is flawed, if you switch toCharArray() and arraycopy() around I bet the results will be different Commented Sep 19, 2014 at 23:03
  • I changed the order: arraycopy: 1584.2 toCharArray: 1364.0. But thanks for the tip, I will try Caliper! Commented Sep 19, 2014 at 23:13

2 Answers 2

2

For "abcdefg".toCharArray(), String.toCharArray()'s source code is

public char[] toCharArray() {
    char result[] = new char[count];
    getChars(0, count, result, 0);
    return result;
}

getChars calls System.arraycopy so its performance with your arraycopy() should be the same. However, String's getChars copies from its internal char[] field, which is declared as final

private final char value[];

Where as your arraycopy() copies from SRC, which is non-final

private static char[] SRC = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };

This is just a guess, but trying making SRC final and see what happens.

Sign up to request clarification or add additional context in comments.

1 Comment

You're right! After I make SRC final the result is: toCharArray: 1332.2 arraycopy: 1322.6. Thanks! So here is optimization. And do you have any idea why init() a bit faster than others?
0

My first guess for my first question was the following:

I thought that the difference between init() and toCharArray() is that the init() skips array initialization with default values. But then I checked the bytecode and I haven't seen any difference.

Later I found this, and when I modified my test to work with a larger array, I realized that toCharArray() is faster!

To my second question I got the answer (thanks again).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.