Оптимизация хвостовой рекурсии и рекурсия в Java

У меня есть вопрос об оптимизации хвостовых вызовов, мне нужно знать, как ведет себя этот код Java:

private void doSomething(int v) {

    inf f = someCalculation(v);

    if (f < 0) doSomething(v/2);
    else doSomething(v*2);

}

Этот код является бессмысленным примером, но мой вопрос, в таком случае:

  1. Первый вызов doSomething() будет оптимизирован?
  2. Второй вызов doSomething() будет оптимизирован?
  3. Блок 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 может запустить его без переполнения стека, то это должно означать, что он может выполнять оптимизацию хвостовой рекурсии (или очень хорошее постоянное распространение).

Другие вопросы по тегам