Оптимизация компилятора Java


недавно я читал этот статьи.

согласно этой статье, компилятор Java, т. е. javac, не выполняет никакой оптимизации при создании байт-кода. Это правда? Если да, то может ли он быть реализован в качестве промежуточного генератора кода для удаления избыточности и генерации оптимального кода?

5 51

5 ответов:

javac только очень мало оптимизации, если таковые имеются.

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

Я перестал читать, когда добрался до этого раздела:

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

во-первых, выполнение цикла развертывания на исходном коде Java является вряд ли это хорошая идея. Причина javac не делает много на пути оптимизации, что это делается JIT-компилятором в JVM, который может принимать гораздо лучшие решения, что компилятор мог бы, потому что он может точно видеть, какой код запускается больше всего.

The javac компилятор когда-то поддерживал возможность генерировать оптимизированный байт-код, передавая -o в командной строке.

однако начиная с J2SE1. 3,точка доступа JVM была поставлена с платформой, который ввел динамические методы, такие как своевременная компиляция и адаптивная оптимизация общих путей выполнения. Отсюда и -o был проигнорирован компилятором Java, запускающим эту версию.

я наткнулся на этот флаг, когда читал о Муравей javac и :

указывает, должен ли источник быть скомпилирован с оптимизацией; по умолчанию off. Примечание что этот флаг просто игнорируют начиная с JDK 1.3 (поскольку оптимизация времени компиляции не требуется).

преимущества динамической оптимизации HotSpot JVM по сравнению с оптимизацией времени компиляции описаны в этот страница:

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

Я изучал выводимый байт-код Java в прошлом (используя приложение под названием FrontEnd). Он в основном не выполняет никакой оптимизации, за исключением встроенных констант (статические финалы) и предварительных вычислений фиксированных выражений (например, 2*5 и "ab"+"cd"). Это часть того, почему это так легко разобрать (с помощью приложения под названием JAD)

Я также обнаружил некоторые интересные моменты для оптимизации вашего кода java. Это помогло мне улучшить скорость внутренних петель в 2,5 раза.

метод 5 переменных быстрого доступа. Когда эти переменные вызываются, они быстрее, чем все другие переменные (вероятно, из-за обслуживания стека). Параметры метода также подсчитываются к этим 5. Поэтому, если у вас есть код внутри цикла for, который выполняется как миллион раз, выделите эти переменные в начале метода и не имеют параметров.

локальные переменные также быстрее, чем поля, поэтому, если вы используете поля внутри внутренних циклов, кэшируйте эти переменные, назначая их a локальная переменная в начале метода. Кэшируйте ссылку, а не содержимое. (например: int[] px = this.пиксели;)

для оптимизации байт-кода можно использовать Proguard.

Как отмечали другие, JIT в основной JVM оптимизирует код по мере его компиляции и, поскольку он имеет доступ к большему контексту, он, вероятно, превзойдет Proguard. Это может быть не так в более простых виртуальных машинах. В мире Android это обычная практика, чтобы использовать ProGuard оптимизации при использовании виртуальной машины Dalvik (виртуальной машины, которая пришла с Android до Lollipop).

Proguard также сжимается и запутывает байт-код, который является обязательным при отгрузке клиентских приложений (даже если вы не используете оптимизацию).