Производительность нового оператора по сравнению с newInstance () в Java

Я использовал newInstance() в своего рода критической по отношению к производительности области моего кода. Сигнатура метода:

T create(Class clasz)

Я передаю Something.class как аргумент, я получаю экземпляр SomethingElse, созданный с newInstance().

Сегодня я возвратился для очистки этой производительности TODO от списка, таким образом, я запустил несколько тестов new оператор по сравнению с newInstance(). Я был очень удивлен потерей производительности newInstance().

Я записал немного об этом, здесь: http://biasedbit.com/new-vs-newinstance/

(Извините за сам продвижение... Я поместил бы текст сюда, но этот вопрос вырастет из пропорций.)

То, что я хотел бы знать, - то, почему делает -server флаг обеспечивает такое повышение производительности, когда количество создаваемых объектов растет в основном а не для "низких" значений, скажем, 100 или 1000.

Я действительно извлекал свой урок с целой вещью отражений, это - просто любопытство об оптимизациях, которые JVM выполняет во времени выполнения, особенно с -server флаг. Кроме того, если бы я делаю что-то не так в тесте, я ценил бы Вашу обратную связь!


Править: Я добавил фазу прогрева, и результаты теперь более стабильны. Спасибо за вход!

10
задан biasedbit 7 August 2013 в 00:08
поделиться

3 ответа

Я усвоил урок, связанный с размышлениями, это просто любопытство по поводу оптимизаций, которые JVM выполняет во время выполнения, особенно с флагом -server. Также, если я делаю что-то не так в тесте, буду благодарен за ваш отзыв!

Отвечая сначала на вторую часть, ваш код, похоже, совершает классическую ошибку для микротестов Java и не «разогревает» JVM перед выполнением ваших измерений. Ваше приложение должно запустить метод, который выполняет тест несколько раз, игнорируя первые несколько итераций ... по крайней мере, до тех пор, пока числа не стабилизируются. Причина этого в том, что JVM должна проделать большую работу, чтобы запустить приложение; например загрузка классов и (когда они запускались несколько раз) JIT-компиляция методов, на которые тратится значительное время приложения.

Я думаю, что причина того, что «-сервер» имеет значение, заключается в том, что (среди прочего) он изменяет правила, определяющие, когда выполнять JIT-компиляцию. Предполагается, что для «сервера» лучше выполнить JIT раньше, это даст более медленный запуск, но лучшую пропускную способность. (В отличие от этого «клиент» настроен на отсрочку JIT-компиляции, чтобы пользователь быстрее получил рабочий графический интерфейс.)

5
ответ дан 4 December 2019 в 02:49
поделиться

IMHO штраф за производительность идет от механизма загрузки классов. В случае отражения используются все механизмы безопасности, поэтому штраф за создание выше. В случае нового оператора классы уже загружены в VM (проверены и подготовлены загрузчиком классов по умолчанию), и фактическая инстанцизация является дешевым процессом. Параметр -server выполняет множество JIT-оптимизаций для часто используемого кода. Возможно, вы захотите попробовать его также с параметром -batch, что приведет к снижению времени запуска, но тогда код будет выполняться быстрее.

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

Среди прочего В частности, профиль сборки мусора для параметра -сервер имеет существенно другие значения по умолчанию размер оставшегося пространства .

При внимательном чтении я вижу, что ваш пример представляет собой микробенкмарк , и результаты могут показаться нелогичными. Например, на моей платформе повторные вызовы newInstance () эффективно оптимизируются во время повторных запусков, в результате чего newInstance () появляется в 12,5 раз быстрее, чем new .

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

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