Bytecode уже теряет довольно много семантики, вот в чем проблема. Это своего рода неструктурированный машинный код. В качестве примера можно увидеть огромную сложность декомпилятора Java: это в основном C.S.I. команда Java, кропотливо восстанавливая исходный код из фрагментов информации, разбросанных по байт-коду.
Поскольку современные JVM не очень полезны для байт-кода, кроме как описания семантики программы, она утратила свою первоначальную цель, которая должна была быть относительно быстро интерпретируемым форматом, промежуточным по уровню описания между Java и собственным машинным кодом.
JIT-компилятор на самом деле имеют труднее время оптимизируя байткод хорошо, чем имели бы с оригинальным исходным кодом, потому что он хочет знать как можно больше о намерениях за кусок кода. Рассмотрим этот фрагмент кода:
int i = 0;
String s = "";
for (Integer num : nums) {
s += num;
if (++i < ints.size()) s += ", ";
}
Что делает код? После некоторого анализа и подтверждения нескольких догадок выясняется, что он собирает строку, разделенную запятыми, из списка целых чисел. Однако есть много возможностей для оптимизации:
- с использованием неизменяемого типа
String
для хранения промежуточных значений через петлю;
- , поддерживающий отдельную индексную переменную,
i
, которая является дубликатом той, которая хранится в неявной Iterator
;
- проверяет
i
на размер списка каждый раз, хотя ясно, что это будет верно только на последней итерации.
JIT-компилятор обычно выполняет цикла специализации Оптимизационный: он будет издавать отдельный код только для последнего шага петли, тем самым полностью исключает повторное if
проверки.Он также может понять, что промежуточные строки не ускользают и автоматически заменяют всю идиому на StringBuilder
.
Для того чтобы все это произошло, ясно, что компилятор должен получить достаточно тщательное понимание на высоком уровне того, что происходит, что будет намного проще с исходным кодом, чем в результате байт-кода.
Современная тенденция в языках программирования заключается в том, чтобы распространять исходный код как точку входа для JIT или что-то очень похожее на исходный код, например, AST.
Этот вопрос лучше подходит для Exchange Programmers. –