Pull to refresh

Comments 14

Есть еще один способ, не волшебный, правда, и не всегда применимый, но мега-крутой - compile-time кодогенерация и post-compile weaving. Последний вообще позволяет получить перфоманс "как будто бы сам написал".

Спасибо за статью. Почему Вы не используете фреймворк для микробенчмаркинга (например, jmh)? Кроме того в 18ой джаве core reflections переписали на var handles.
https://openjdk.java.net/jeps/416

Про var handles не знал, спасибо. Что насчет jmh, в данном случае его использование показалось излишним, все измерения сводились к вызову нескольких методов, да и точности используемого подхода вполне хватает.

А кеширование как вариант почему не рассматривается?

Каким образом кэширование поможет ускорить рефлективные вызовы метода? Имхо, максимум можно кэшировать получение объекта java.lang.reflect.Method, но это даст выигрыш лишь в скорости подготовки вызова.

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

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

А можете еще чуть подробнее пояснить свою мысль? Вы же показываете код на C++, то есть, так или иначе, это не байткод.

Ну смотрите. Байт-код можно либо интепретировать, либо компилировать в платформенный код. В обоих случаях мы можем вместо какого-то метода JVM вызвать просто какую-нибудь функцию самой JVM, чем и являются интринсики.

Ну а JNI - это сложнейший комбайн, который поддерживает потокобезопасность, открывает во внешний мир API JVM и делает еще кучу вещей, необходимых для стабильного FFI.

Я правильно понял, что этот код на C++, не компилируется в .so или .dll, и не вызывается через JNI, а является частью хотспот компилятора?

Да. Если бы для каждого вызова интринсика приходилось уходить в safe point, то это было бы больно.

Рефлексия в Джаве помимо пользы может нести в себе кучу багов, которые потом хрен поймаешь. А так же это - отличный инструмент в руках хакера/злоумышленника. Получить доступ можно к чему угодно.

Занимательные замеры времени. Вывод же несколько ограниченный. Вся разница получается за счёт компиляции метода add в одну asm инструкцию вместо нескольких десятков для reflection-а. Ну а промежуточные значения есть лишь показатель способности методом тыка подсказать компилятору, как же правильно компилировать.

Ну и про "тяжесть" рефлексии. Просто не надо писать критический код с её использованием. И в подавляющем большинстве случаев для этого нет никакой необходимости. А некритический код, исполняемый за 1 микросекунду или за 10 наносекунд - абсолютно ни на что не влияет.

Only those users with full accounts are able to leave comments. Log in, please.