Я видел нечто подобное. «Ручное встраивание» не обязательно быстрее, результирующая программа может быть слишком сложной для анализа оптимизатором.
В вашем примере давайте сделаем некоторые дикие догадки. Когда вы используете метод swap (), JVM может анализировать тело метода и сделать вывод, что, поскольку i и j не меняются, хотя имеется 4 доступа к массиву, требуется только 2 проверки диапазона вместо 4. Также Локальная переменная t
не требуется, JVM может использовать 2 регистра для выполнения работы, без использования r / w t
в стеке.
Позже тело swap () встраивается в метод вызывающей стороны. Это после предыдущей оптимизации, поэтому сохранения все еще на месте. Возможно даже, что тело метода вызывающей стороны доказало, что i и j всегда находятся в пределах диапазона, поэтому 2 оставшиеся проверки диапазона также отбрасываются.
Теперь в версии, встроенной вручную, оптимизатор должен анализировать всю программу сразу, слишком много переменных и слишком много действий, он может не доказать, что безопасно сохранять проверки диапазона или удалять локальную переменную t
. В худшем случае эта версия может потребовать еще 6 обращений к памяти для выполнения подкачки, что является огромным издержками. Даже если читается только 1 дополнительная память, это все равно очень заметно.
Конечно, у нас нет оснований полагать, что всегда лучше выполнять ручное «обрисовывание», то есть извлекать небольшие методы, желая думать, что это поможет оптимизатору.
-
То, что я узнал, это то, что забудь ручную микрооптимизацию. Дело не в том, что мне небезразлично улучшение микропроцессора, я не всегда доверяю оптимизации JVM. Это то, что я понятия не имею, что делать, что приносит больше пользы, чем зла. И я сдался.