【问题标题】:Is functional language wasting memory?功能性语言会浪费记忆吗?
【发布时间】:2014-05-03 22:11:34
【问题描述】:

总的来说,我想问一下,

  • 如果一个问题既可以通过命令式语言方式也可以通过函数式语言方式解决,与命令式语言相比,函数式语言会浪费内存,至少不会节省内存,因为 em>,函数语言大量依赖递归,递归压栈大量内存

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


以上问题,其实来自一个算法问题:

保留堆栈而不使用额外空间:

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);
}

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


当然,我的问题更笼统,你不必专注于上面的具体问题。

感谢您的周到建议!

【问题讨论】:

  • 阅读“尾递归”和相关概念。函数式语言可以进行一些有趣的优化,因为程序可以进行数学证明。
  • 我知道“尾递归”,在这种情况下,命令式语言和函数式语言是等价的(尾递归可以转移到循环中)。但是,我的问题更侧重于内存效率,即。在一个巨大的数组中进行二分搜索...
  • 我的意思是尾递归不需要额外的堆栈内存,所以仅仅使用函数式语言并不意味着使用更多的资源。
  • 我同意你的看法。在这种情况下 Func.Lang。不比命令式差,但也不比命令式好,对吧?

标签: memory memory-management recursion functional-programming imperative-programming


【解决方案1】:

在理论上,没有。您始终可以将迭代算法转换为递归算法,反之亦然。假设相同的算法并使用尾调用优化实现,内存消耗的大O将完全相同。

在实际意义上,也许吧。在函数式编程中使用不可变数据结构的风格会占用大量内存。

IMO,使用函数式编程与命令式编程是风格的问题。使用最适合代码的那个。而且,如果您需要机器的所有性能,您可以随时编写手动优化的程序集。

【讨论】:

  • 谢谢!我同意这是风格问题。假设您是公司的程序员(您无法编写手动优化的程序集),从内存效率的角度来看,如果没有必要,您应该倾向于使用命令式语言。?
  • 如果我要决定在项目中使用哪种语言(我认为这是您在问题中所要解决的问题),内存效率是首要考虑因素,我会考虑每种语言的记忆效率,而不是每种风格。就像@IMSoP 所说,作为一种函数式语言并不一定意味着更多的内存消耗,而命令式并不一定意味着更少。相反,我会认识到低级语言(C、C++)可以更好地控制内存消耗,而高级语言(Python、Java、Haskell)则不能。
【解决方案2】:

没那么容易。

首先,递归,特别是尾递归不需要比循环更多的内存。一般情况下,尾调用也是如此。尾调用,无论是否递归,总是可以编译为跳转/分支指令,if 目标机器语言允许这样做。因此,函数式语言中的程序不需要比命令式语言中的类似程序具有更大的堆栈。

另一方面,为了尽量减少副作用,函数式编程更喜欢处理不可变数据,实际上函数式编程允许不可变数据。因此,函数式数据结构往往比命令式语言中的可变数据结构更耗费内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2010-12-28
    • 2016-09-28
    • 2020-07-07
    • 2012-08-03
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多