递归的高级语言代码更简短,利于书写,且易于理解,可读性高。
然而,递归的MIPS指令却更为复杂,原因如下:
由于寄存器数量的限制,MIPS在每次调用下一层函数时,都需要将本层放在寄存器中的数据压栈保存(如本层的返回地址$ra),以空出寄存器给下一层函数使用。通俗地讲,寄存器就是公共资源,数量有限,当不用时需要放弃对其占有的状态,方便他人使用。
当递归次数增多时,这样就大大增加了堆栈的压力,容易造成堆栈溢出。
而迭代就大大减少了堆栈的压力,而且省去了不断的调用与返回的操作,在性能上是大大优于递归的。唯一的缺点就在于相对于递归更加难以理解,代码行数也会增加。
递归与迭代的代码如下(C++与MIPS):
递归:
int sum(int n, int acc) //recursion
{
if(n<1)
return acc;
else
return sum(n-1, acc+n);
}
MIPS(n: $s0 acc: $s1):
sum:addi $sp, $sp, -4
sw $ra, 0($sp) #save $ra
slti $t0, $s0, 1
beq $t0, $zero, L1 #if $s0>0, jump to sum_exit
addi $sp, $sp, 4
add $v0, $s1, $zero
jr $ra
L1: add $s1, $s1, $s0
addi $s0, $s0, -1
jal sum #recursive invocation
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
迭代
int sum(int n, int acc) //iteration
{
while(n>0)
{
acc += n;
n -=1;
}
return acc;
}
MIPS(n: $s0 acc: $s1)
sum:slti $t0, $s0, 1
bne $t0, $zero, sum_exit #if $s0<1, jump to sum_exit
add $s1, $s1, $s0 #else $s1=$s1+$s0
addi $s0, $s0, -1 # $s0=$s0-1
j sum #iteration
sum_exit:
add $v0, $s1, $zero
jr $ra