tail recursion

来源:互联网 发布:浙江华为 知乎 编辑:程序博客网 时间:2024/06/10 22:36

traditional recursion: perform recursion first, then take the return value of the recursive call and calculate the result. You don’t get the result of your calculation until you have returned from every recursive call.

int sum(int i) {    if (i==0) return 0;    else return sum(i-1)+i;}int foo(void){    return sum(10000000);}
mov rdi,10000000call sumret; sum function: computes sum of numbers from 0...i; one parameter: i, in rdi: number of recursions leftsum:cmp   rdi,0 ; check if we're donejle    base_casepush rdisub  rdi,0x1; i-1call sum ; recursion steppop rdiadd rax,rdi ; partial + iretbase_case: ; no more iterations--return zeromov   rax,0ret

Because calling functions takes some overhead (push return address, call function, do work, pop return address, return there), recursion is slower than iteration.

tail recursion: perform your calculations first, and then you execute the recursive call, passing the results of your current step to the next recursive step. This results in the last statement being in the form of “(return (recursive-function params))” . Basically, the return value of any given recursive step is the same as the return value of the next recursive call.
Key here is for there to be nothing for the function to do after recursion, there is no point in your children returning to you.

int sum(int i,int partial) {    if (i==0) return partial;    else return sum(i-1,partial+i);}int foo(void){    return sum(10000000,0);}
mov edi,1000000000 ; sum first argumentmov esi,0 ; partial resultcall sumretsum:mov    eax,esicmp   edi,0je    base_caselea    esi,[rax+rdi*1] ; funky esi=eax+edisub    edi,0x1jmp sum ; tail recursion step!base_case:ret

Reference:
https://stackoverflow.com/questions/33923/what-is-tail-recursion
https://www.cs.uaf.edu/2012/fall/cs301/lecture/09_24_call_and_ret.html

原创粉丝点击