Можно ли написать достойный оптимизатор Java, если информация теряется при переводе в байт-код? - PullRequest
1 голос
/ 04 февраля 2009

Мне пришло в голову, что когда вы пишете программу на C, компилятор знает исходную и целевую платформы (из-за отсутствия лучшего термина) и может оптимизироваться под машину, для которой он строит код. Но в java лучшее, что может сделать компилятор, это оптимизировать под байт-код, что может быть здорово, но в jvm все еще есть слой, который должен интерпретировать байт-код, и чем дальше байт-код удален от конечной архитектуры машины чем больше работы нужно сделать, чтобы это пошло.

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

Так можно ли вообще приблизиться к эффективности C с помощью компилятора Java?

Ответы [ 4 ]

5 голосов
/ 04 февраля 2009

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

4 голосов
/ 04 февраля 2009

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

3 голосов
/ 04 февраля 2009

Теоретически оба оптимизатора должны вести себя «одинаково», поскольку для компиляторов c / c ++ стандартная практика - выполнять оптимизацию сгенерированной сборки, а не исходного кода, поэтому вы уже потеряли семантическую информацию.

2 голосов
/ 04 февраля 2009

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

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

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

Java 7 поддерживает анализ экранирования для заблокированных / синхронизированных объектов, он может обнаружить, что объект используется только в локальном контексте, и удалить синхронизацию для этого объекта. В текущих версиях Java он может определять, блокируют ли два последовательных метода один и тот же объект, и сохранять блокировку между ними (вместо того, чтобы освобождать и повторно получать блокировку) Вы не можете сделать это с C / C ++, потому что нет понимания уровня блокировки языка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...