Мемоизация с Вавром кажется незаметной
Когда функция определяется следующим образом
static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) ->
value.equals(BigInteger.ZERO) ? BigInteger.ZERO
: value.equals(BigInteger.ONE) ? BigInteger.ONE
: value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE
: Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2))))
).memoized();
И называется
System.out.println(fibonacci.apply(BigInteger.valueOf(1000)));
Он рассчитан очень быстро. Однако, если я перееду memoized()
функционировать переменную следующим образом
static Function1<BigInteger, BigInteger> fibonacci = Function((BigInteger value) ->
value.equals(BigInteger.ZERO) ? BigInteger.ZERO
: value.equals(BigInteger.ONE) ? BigInteger.ONE
: value.equals(BigInteger.valueOf(2)) ? BigInteger.ONE
: Program.fibonacci.apply(value.subtract(BigInteger.ONE)).add(Program.fibonacci.apply(value.subtract(BigInteger.valueOf(2))))
); // Removed memoized() from here
И называется
fibonacci.memoized().apply(BigInteger.valueOf(1000));
Это занимает очень много времени, как будто memoized()
не был применен.
Что может быть причиной этого?
1 ответ
Решение
Потому что а) рекурсия не вызывается в запоминаемой форме, б) весь смысл запоминания заключается в том, что вам нужно сохранить запоминание, а не создавать новое запоминание каждый раз.
Program.fibonacci
определяется в терминах самого себя, поэтому рекурсия вызывает эту версию, а не запомненную версию.