В чем смысл JIT не компилировать огромные методы?

Мне было интересно, почему компилятор JVM JIT игнорирует "огромные методы" из компиляции. (Если для флага DontCompileHugeMethods установлено значение false). В то же время большинство разговоров о компиляторе Java JIT указывают, что inlining - это оптимизация uber, так как позволяет увеличить массу инструкций, подлежащих компиляции. И этот более крупный контекст компиляции позволяет лучше оптимизировать исполняемый код. При этом я бы предположил, что огромный метод не сильно отличается от сильно встроенного метода и должен стать отличной мишенью для компиляции JIT. Что мне здесь не хватает?

Ответ 1

По сути, рентабельность компиляции огромных методов низкая.

  • Горячие фрагменты кода обычно короткие.

  • Даже если часто выполняется огромный метод, горячая часть вряд ли охватит весь метод. Например. рассмотрим большой оператор switch, где часто выполняется только несколько меток case. Однако модуль компиляции - это метод, поэтому большая часть кода JITted будет пустой тратой.

  • Компиляция огромных методов занимает много времени и места. Более того, время компиляции не растет линейно. Вместо этого было бы выгоднее скомпилировать несколько небольших методов.

  • Слишком длинный лист машинного кода загрязняет кэш инструкций.

  • Определенные оптимизации лучше применять к меньшим частям кода, например Распределение регистра или развертывание цикла.

  • Если один метод больше 8K байт-кодов, он все равно плохо написан.

Ответ 2

Th 8k предел, вероятно, просто устаревшая эвристика. В прежние времена [ТМ] JITing был несколько дорогостоящим (особенно если смотреть с точки зрения отзывчивости). На самом деле, наиболее интересные оптимизации (например, свертывание констант, хорошее распределение регистров и т.д.) Являются суперлинейными. Следовательно, вы хотите быть особенно осторожными, чтобы не останавливать весь процесс на полсекунды для запуска задачи оптимизации, которая может дать лишь часть этого времени в виде увеличения производительности.

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