嗨,我是Erlang世界的新手。当我想到我们需要如何解决以下问题时(并且有一长串类似的问题),我认为它真的效率很低,因为我们说的是很多递归。显然,像C / Java这样的语言不需要笨拙的递归来解决这个问题,但是对于Erlang(我猜其他函数式编程语言也需要,也许?)你必须这样做。
示例3 - 附加
该程序连接两个列表:
append([], List) -> List;
append([First|Rest], List) -> [First | append(Rest,List)].
任何人都可以解释为什么这不是问题吗?
答案 0 :(得分:12)
首先,阅读递归的Erlang efficiency guide。
至于笨拙,不要忘记Erlang列表是单链表,所以你只有一个指向列表头部的“指针”,需要通过遍历列表来访问元素。 这将需要相同的数量,但不同类型的笨拙与所有指针或参考杂耍的语言。
至于效率,您可以以尾递归的方式实现它。尾递归被优化(see this SO question),使得编译的代码变得类似于你在C ++中实现的那样,唯一的区别是代替指针跳转,堆栈指针是倒带等等。
无论如何,尝试在Java和C ++中实现完全相同的功能,然后我们将看到哪一个更笨拙且更具可读性。
答案 1 :(得分:6)
嗨,我是C世界的新手。当我想到我们需要如何解决以下问题时(并且有一长串类似的问题),我认为这是非常低效的,因为我们说的是很多循环。显然,像Erlang这样的语言不需要笨拙的循环来解决这个问题,但是使用C(我猜其他程序编程语言也需要,也许?)你必须这样做。
看看我在那里做了什么? ;)
正如其他人所说,递归是一种完全正常(和有效)的方式来解决许多语言的问题。没有直接相关,但是......对于某些事情来说,递归比循环更容易理解(反过来也是如此)...... fib(n)。
答案 2 :(得分:4)
那么,为什么你认为递归效率低下?
在Erlang的情况下,它使用尾递归(.Net IL也可以这样做),实际上在处理方面效率稍高。
例如,使用尾递归,CPU会执行以下操作:
var first_list, second_list
label START_ITER:
if(first_list is empty)
goto FINISH
var first_elem = first_list[0]
var first_list.start_element = first_list[1]
second_list[n+1] first_elem
goto START_ITER
label FINISH:
return second_list
对于for循环,你得到这样的东西:
var first_list, second_list
var i = 0
var limit = first_list.length
label START_ITER:
if(i == limit)
goto FINISH
second_list[n+i+1] = first_list[i]
i += 1
goto START_ITER
label FINISH:
// Done
尾部递归示例需要注意的是,列表拆分只会更改first_list指向的列表中的节点。 for循环示例使用更多变量赋值来做同样的事情。
这也说明了尾递归(只是一个goto)和正常递归之间差异的重要一点,它实际上会将一个函数加载到堆栈上。这种情况不会发生在尾递归和一般的erlang中。
这是一个近距离调用,但在for循环中有一些额外的检查和添加,所以我不能在效率方面推荐一个,但它的风格,递归条款完美地完成了。
我认为最好把它作为“迭代是人,回归,神圣”
答案 3 :(得分:0)
尾递归在每种函数语言中都得到了优化 - 与过程语言的循环(或者,ahem,goto ;-)相比,它没有任何开销。虽然您提供的具体示例可能是也可能不是“尾递归”,具体取决于语言(懒惰与急切的函数语言,例如),当您使用一种特定语言进行编码时,通常可以重构为纯尾递归表达式......如果需要的话。
用惰性语言,例如Haskell,append
(Haskell相当于)[First | append(Rest, List)]
将被保存为“thunk”,以便在需要时执行,而不是立即急切扩展。然后,当稍后某个模式匹配thunk与头/尾结构时 - 然后,只有这样,thunk才会被执行。
渴望(非懒惰)的语言有不同的方法,但效率并不低(尽管懒惰语言的粉丝可能认为它不那么优雅; - )。
答案 4 :(得分:0)
您可能不知道“erlc -S”和“to_core”选项,它们允许您检查字节码(BEAM或HiPE)
pattern matching - implementation
http://www.nabble.com/Re%3A-Idiomatic-Erlang%2C-style-performance-question-p18061921.html
HTH