Я пытался улучшить Энди ответ , но он в значительной степени прибил его.Первое решение - это создание пирамиды потоков - каждый вызов fib
создает еще один поток Фибоначчи, и каждый из этих новых потоков сам создаст новый поток и т. Д.
Чтобы быть понятным, есть три потока в результате вызова к fib
:
- Один создан
fib
в fib zip fib.tail
- Один создан
fib.tail
в fib zip fib.tail
- Созданный
map
(помните, map
создает новую коллекцию)
Поскольку первые два вызова fib
они будут создавать по три потока каждый и т. д.
Вот примерная «картина» этого:
1
1
1 2 1
1 3 1 2 1
1 2 1 5 1 3 1 2 1
1 3 1 2 1 8 1 2 1 5 1 3 1 2 1
И это продолжается и продолжается.Средний поток вычисляется с использованием самых высоких потоков слева и справа (fib и fib.tail).Каждый из них вычисляется с использованием нижних потоков на их влево и вправо.Каждый из этих более низких потоков вычисляется с использованием потоков, показанных в последней строке.
Мы могли бы продолжать это снова и снова, но вы можете видеть, что к тому времени, как мы вычислили 8, у нас уже есть 14 других потоков Фибоначчи
Если вы измените его с def
на val
, все эти новые потоки исчезнут, потому что fib
и fib.tail
будут ссылаться на существующий поток вместо созданияновые потоки.И поскольку новый поток не будет создан, больше не будет звонков на fib
и fib.tail
.
Теперь, если вы посмотрите на второй ответ, вы заметите, что есть один fib
вызов, а не map
или подобный метод, поэтому эффект умножения отсутствует.