В функциональном программировании почти все структуры данных являются неизменными, когда состояние должно измениться, создается новая структура. Значит ли это, что использование памяти будет намного больше?
Это зависит от структуры данных, точных внесенных вами изменений и, в некоторых случаях, от оптимизатора. В качестве одного примера давайте рассмотрим добавление в список:
list2 = prepend(42, list1) // list2 is now a list that contains 42 followed
// by the elements of list1. list1 is unchanged
Здесь потребность в дополнительной памяти постоянна, как и стоимость вызова во время выполнения prepend
. Почему? Потому что prepend
просто создает новую клетку, у которой есть 42
голова и list1
хвост. Для этого не нужно копировать или иным образом перебирать list2
. То есть, за исключением памяти, необходимой для хранения 42
, list2
повторно используется та же память, которая используется list1
. Поскольку оба списка являются неизменными, это совместное использование совершенно безопасно.
Аналогично, при работе со сбалансированными древовидными структурами большинству операций требуется только логарифмическое количество дополнительного пространства, потому что все, кроме одного пути дерева, может быть общим.
Для массивов ситуация немного другая. Вот почему во многих языках FP массивы не так часто используются. Однако, если вы делаете что-то подобное arr2 = map(f, arr1)
и arr1
больше никогда не используете после этой строки, умный оптимизатор может фактически создавать код, который мутирует, arr1
вместо создания нового массива (не влияя на поведение программы). В этом случае производительность будет, как и на императивном языке, конечно.