varargs производительность Java

Кодирование я пришел для проверки на vararg производительность Java.

Я пишу следующий тестовый код:

public class T {

    public static void main(String[] args) {

        int n = 100000000;
        String s1 = new String("");
        String s2 = new String("");
        String s3 = new String("");
        String s4 = new String("");
        String s5 = new String("");

        long t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            foo();
        }
        System.err.println(System.currentTimeMillis() - t);


        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            baz(s1, s2, s3, s4, s5);
        }
        System.err.println(System.currentTimeMillis() - t);

        t = System.currentTimeMillis();
        for (int i = 0; i < n; i++) {
            bar(s1, s2, s3, s4, s5);
        }
        System.err.println(System.currentTimeMillis() - t);

    }

    static void foo() {
    }

    static void bar(String a1, String a2, String a3, String a4, String a5) {
    }

    static void baz(String... a) {
    }
}

На моей машине средний вывод:

78
4696
78

Кажется, что переменные передачи к методам бесплатно?! Хороший!

Но использование varags 60x медленнее! Почему?

Объяснение могло состоять в том, что программа должна создать массив на "куче", и время, тратят GC. Но для меньшего количества циклов я все еще добираюсь, как произведено:

0
62
0

Что проводит это дополнительное время для, и так или иначе компилятор имеет всю информацию для разрешения этого к вызову переменной фиксации...

Не мое намерение оптимизировать для этого, но я нашел это любопытным...

Обновление

Я добавил новый тест

t = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
    baz(s1);
}
System.err.println(System.currentTimeMillis() - t);

И эта версия аргумента все еще 30x медленнее. Возможно, существует ArrayList.toArray () позади сцены?

Так знайте о ненеобходимых varags методах в своем коде и осуществите рефакторинг для фиксации длины. Это могло быть повышением производительности.

15
задан PeterMmm 11 March 2010 в 16:36
поделиться

3 ответа

Статический список аргументов сильно отличается от массива. Когда вы передаете их таким образом, компилятор резервирует место для ссылок и заполняет их при вызове метода.

Varargs - это эквивалент массива. Чтобы вызвать такой метод, необходимо создать и заполнить массив во время выполнения. Вот почему вы наблюдаете разницу.

String[] и String... являются синонимами. Если вы сравните их, то увидите идентичную производительность.

19
ответ дан 1 December 2019 в 02:29
поделиться

Как сказано, массив сохраняется при использовании var-args ...,

вам также следует попытаться увидеть влияние добавления "final" к параметрам каждого метода

Я лично получаю улучшение от 2250 -> 2234 мс для массива.

0
ответ дан 1 December 2019 в 02:29
поделиться

Интересная проблема!

Это всего лишь предположение: за кулисами Var-args - это просто массивы. Создание этого неявного массива и заполнение его параметрами var-args может занять некоторое время; следовательно th Падение производительности. Ну, наверное.

1
ответ дан 1 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: