Оптимизация с помощью компилятора Java - PullRequest
58 голосов
/ 12 мая 2011

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

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

Ответы [ 5 ]

78 голосов
/ 12 мая 2011

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

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

25 голосов
/ 12 мая 2011

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

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

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

14 голосов
/ 14 февраля 2016

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

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

Я столкнулся с этим флагом, когда читал о задаче Ant javac и ее атрибуте optimize:

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

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

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

8 голосов
/ 12 мая 2011

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

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

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

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

1 голос
/ 10 апреля 2017

Для оптимизации вашего байт-кода вы можете использовать Proguard .

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

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

...