Комментаторы уже указали, что JIT, вероятно, вызывает такое поведение, но кажется, что ОП не знает, что это такое. Так что просто кратко объясню:
Ваша виртуальная машина Java может запустить программу двумя способами:
Интерпретация байт-кода Java. По сути, интерпретатор «обходит» байт-коды один за другим, проверяет, что каждый из них, и выполняет соответствующее действие.
Преобразование байт-кода в машинный код, который базовый ЦП может запускать напрямую. Это называется «Компиляция точно в срок» или JIT.
Программы, которые были JIT-обработаны для машинного кода, работают намного быстрее, но компиляция требует времени, что может замедлить запуск программы. Таким образом, ваша JVM идет на компромисс: изначально она просто интерпретирует байт-код, но если определенный метод выполняется много раз, JIT компилирует , этот отдельный метод только . Обычно только небольшая часть программного кода будет выполняться много раз (внутренние циклы и т. Д.), Поэтому эта стратегия эффективна.
Результатом этого является то, что когда вы тестируете код Java, вы должны сначала "прогреть" JVM, выполняя ваш код в цикле достаточное количество раз, чтобы все критичные для производительности методы были скомпилированы JIT.
В этом случае ваше рекурсивное решение, похоже, выиграет от компиляции JIT намного больше, чем решение с использованием грубой силы. Это может указывать на то, что JIT-компилятор находит некоторую оптимизацию, которая значительно выигрывает у рекурсивного решения - возможно, преобразование этих рекурсивных вызовов в итеративный код?