Memory 函数式语言是在浪费内存吗?

Memory 函数式语言是在浪费内存吗?,memory,memory-management,recursion,functional-programming,imperative-programming,Memory,Memory Management,Recursion,Functional Programming,Imperative Programming,总的来说,我想问 如果一个问题可以通过命令式语言和函数式语言两种方式解决,那么函数式语言是否会浪费内存,至少不会节省内存,与命令式语言相比,,因为函数式语言大量回复递归,递归推送大量的内存堆栈? 接着是上面的问题,从内存优化的角度来看,如果一项工作可以用命令式语言完成,那么它不应该(至少不会比)使用函数式语言吗 上述问题实际上来自一个算法问题: 在不使用额外空间的情况下保留堆栈: 上面的问题可以通过使用双递归来解决,在我看来,即使它在代码中没有使用附加内存,它实际上也“隐藏”了堆栈中的附加

总的来说,我想问

  • 如果一个问题可以通过命令式语言和函数式语言两种方式解决,那么函数式语言是否会浪费内存,至少不会节省内存,与命令式语言相比,,因为函数式语言大量回复递归,递归推送大量的内存堆栈

  • 接着是上面的问题,从内存优化的角度来看,如果一项工作可以用命令式语言完成,那么它不应该(至少不会比)使用函数式语言吗


上述问题实际上来自一个算法问题:

在不使用额外空间的情况下保留堆栈:

上面的问题可以通过使用双递归来解决,在我看来,即使它在代码中没有使用附加内存,它实际上也“隐藏”了堆栈中的附加空间


当然,我的问题更一般地说,你们不必关注上面的具体问题


谢谢你周到的建议

从理论上讲,不可以。你总是可以将迭代算法转换为递归算法,反之亦然。假设使用相同的算法并通过尾部调用优化实现,内存消耗的big-O将完全相同

从实际意义上讲,也许是这样。在函数式编程中使用不可变数据结构的方式可能会占用大量内存

在我看来,使用函数式编程和命令式编程是一种风格。使用最适合代码的代码。而且,如果您需要机器的每一点性能,您可以随时编写手动优化的汇编。

这并不容易

首先,递归,特别是尾部递归不需要比循环更多的内存。一般来说,尾部调用也是如此。如果目标机器语言允许,尾部调用(无论是递归还是非递归)始终可以编译为跳转/分支指令。因此,函数式语言中的程序不需要比命令式语言中的类似程序具有更大的堆栈


另一方面,为了最小化副作用,函数式编程更喜欢处理不可变数据,事实上,纯函数式编程只允许不可变数据。因此,函数式数据结构往往比命令式语言中的可变数据结构占用更多内存。

请阅读“尾部递归”和相关概念。函数式语言可以进行一些有趣的优化,因为程序可以进行数学证明。我知道“尾部递归”,在这种情况下,命令式语言和函数式语言是等价的(尾部递归可以转换为循环)。然而,我的问题更多地集中在内存效率上,即在一个巨大的数组中进行二进制搜索…我的观点是尾部递归不需要额外的堆栈内存,所以仅仅使用函数式语言并不意味着自动使用更多的资源。我同意你的观点。在本例中,Func.Lang。不比命令差,也不比命令好,对吧?谢谢!我同意这是风格问题。假设您是公司的程序员(您无法编写手动优化的程序集),从内存效率的角度来看,如果没有必要,您应该倾向于使用命令式语言。如果我决定在项目中使用哪种语言(我认为这就是您在问题中的意思),记忆效率是最主要的考虑因素,我会考虑每种语言的记忆效率,而不是每种风格。正如@IMSoP所说,作为一种函数式语言并不一定意味着更多的内存消耗,而命令式语言也不一定意味着更少的内存消耗。相反,我认为低级语言(C,C++)可以更好地控制内存消耗,而高级语言(Python,Java,Haskell)则不能。
void insert_at_bottom(node **stack, int data)
{
     if( isempty(*stack) ){
      push(stack,data);
      return;
     }
     int temp=pop(stack);
     insert_at_bottom(stack,data);
     push(stack,temp);
}  


void rev_stack(node **stack)
{
     if( isempty(*stack) ) return;
     int temp = pop(stack);
     rev_stack(stack);
     insert_at_bottom(stack,temp);
}