簡體   English   中英

為什么在 C 和 python 中遞歸四分法比迭代四分法快?

[英]why is recursive tetration faster than iterative tetration in C and python?

我在Python中寫了以下兩個四分函數:

def recur_tet(b, n):
    if n == 1:
        return(b)
    else:
        return(b ** recur_tet(b, n - 1))

def iter_tet(b, n):
    ans = 1
    for i in range(n):
        ans = b ** ans
    return(ans)

而且,令人驚訝的是,遞歸版本稍微快一點:

python3> %timeit recur_tet(2,4)
1 µs ± 12.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

python3> %timeit iter_tet(2,4)
1.15 µs ± 14.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

我認為這可能與 Python 的解釋方式有關,所以我做了一個 C 版本:

/* tetration.c */
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int recur_tet(int b, int n){
    if(n == 1){
        return(b);
    }
    else{
        return(pow(b, recur_tet(b, n - 1)));
    }
}

int iter_tet(int b, int n){
    int ans = 1;
    int i;
    for(i = 1; i <= n; i++){
        ans = pow(b, ans);
    }
    return(ans);
}

int main(int argc, char *argv[]){
    /* giving an argument of "1" will do a recursive tetration
    while an argument of "2" will do an iterative one */
    if(atoi(argv[1]) == 1){
        recur_tet(2,4);
    }
    else if(atoi(argv[1]) == 2){
        iter_tet(2,4);
    }
    return(0);
}

遞歸版本仍然更快:

> gcc tetration.c -o tet.o
> time(while ((n++ < 100000)); do ./tet.o 1; done)

real    4m24.226s
user    1m26.503s
sys     1m32.155s
> time(while ((n++ < 100000)); do ./tet.o 2; done)

real    4m40.998s
user    1m30.699s
sys     1m37.110s

因此,這種差異似乎是真實的。 組裝的 C 程序(由gcc -S返回)將recur_tet表示為 42 條指令,而iter_tet是 39 條指令,所以看起來遞歸的應該更長? 但我對組裝一無所知,所以誰知道。

無論如何,有沒有人知道為什么每個 function 的遞歸版本更快,盡管關於遞歸與迭代的普遍智慧? 我是否以一種愚蠢的方式編寫我的迭代版本,並且我沒有看到一些低效率?

Python 和 C 比較的問題在於遞歸和迭代算法並不真正等效(即使它們應該產生相同的結果)。

n1時,遞歸版本立即返回b ,不執行冪運算。 但是在這種情況下,迭代版本正在求冪(Python 中的b**1和 C 中的pow(b, 1) )。 這解釋了迭代版本的速度較慢。

所以一般來說,迭代版本比遞歸版本多做一次冪調用。

為了進行公平比較,要么更改遞歸版本以在n1時進行取冪,要么更改迭代版本以避免它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM