Оптимизация хвостовой рекурсии и рекурсия в Java
У меня есть вопрос об оптимизации хвостовых вызовов, мне нужно знать, как ведет себя этот код Java:
private void doSomething(int v) {
inf f = someCalculation(v);
if (f < 0) doSomething(v/2);
else doSomething(v*2);
}
Этот код является бессмысленным примером, но мой вопрос, в таком случае:
- Первый вызов doSomething() будет оптимизирован?
- Второй вызов doSomething() будет оптимизирован?
- Блок if/else как-то влияет на оптимизацию?
Спасибо
РЕДАКТИРОВАТЬ:
Пожалуйста, приведите пример того, как бы вы сделали это, если бы язык был не Java, а другой, имеющий TCO.
2 ответа
В Java 8 вообще отсутствует оптимизация вызовов. Никакие вызовы не будут оптимизированы (превращены в операторы итерации / перехода).
Обсуждение TCO для Java имеет долгую историю, однако Гай Стил является одним из самых известных его сторонников.
Я рекомендую прочитать этот пост от mlvm-dev
список рассылки для недавнего обзора предмета.
Попробуйте запустить следующий код:
public static void main(String[] args) {
for (int i = 1; i > 0; i *= 2) { doSomething(i); }
}
private static void doSomething(int start) {
doSomething(start, start);
}
private static void doSomething(int i, int start) {
if (i == 0) { System.out.println("done from " + start); }
else { doSomething(i - 1, start); }
}
Если JVM может запустить его без переполнения стека, то это должно означать, что он может выполнять оптимизацию хвостовой рекурсии (или очень хорошее постоянное распространение).