Инициализация массива - различия в производительности

Если я запускаю эту программу, вывод:

init: 1239.0
toCharArray: 1343.6
arraycopy: 1583.8

Первый вопрос:
Зачем init() быстрее чем toCharArray()? Есть ли здесь оптимизация компилятора? (Я использую Java 1.8.0_20)

Второй вопрос:
Зачем toCharArray() быстрее чем arraycopy()? Я скопировал arraycopy() отсюда: 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] = ' ';
    }

}

РЕДАКТИРОВАТЬ

Результат суппорта:

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

2 ответа

Решение

За "abcdefg".toCharArray(), String.toCharArray() исходный код

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

getChars звонки System.arraycopy так что его производительность с вашим arraycopy() должно быть таким же. Тем не менее, String's getChars копии с его внутреннего char[] поле, которое объявлено как окончательное

private final char value[];

Где как твой arraycopy() копии с SRC, который не является окончательным

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

Это всего лишь предположение, но попытка сделать SRC окончательно и посмотрим, что получится.

Моим первым предположением для моего первого вопроса было следующее:

Я думал, что разница между init() а также toCharArray() это то, что init() пропускает инициализацию массива со значениями по умолчанию. Но затем я проверил байт-код и не увидел никакой разницы.

Позже я нашел это, и когда я изменил свой тест для работы с большим массивом, я понял, что toCharArray() быстрее!

На мой второй вопрос я получил ответ (еще раз спасибо).

Другие вопросы по тегам