首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的递归Fibonacci实现要比迭代实现慢呢?

为什么我的递归Fibonacci实现要比迭代实现慢呢?
EN

Stack Overflow用户
提问于 2018-03-01 14:52:19
回答 1查看 1.4K关注 0票数 4

我创建了以下简单的Fibonacci实现:

代码语言:javascript
复制
#![feature(test)]
extern crate test;

pub fn fibonacci_recursive(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
    }
}

pub fn fibonacci_imperative(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => {
            let mut penultimate;
            let mut last = 1;
            let mut fib = 0;
            for _ in 0..n {
                penultimate = last;
                last = fib;
                fib = penultimate + last;
            }
            fib
        }
    }
}

我创建它们是为了试用cargo bench,因此我编写了以下基准测试:

代码语言:javascript
复制
#[cfg(test)]
mod tests {
    use super::*;
    use test::Bencher;

    #[bench]
    fn bench_fibonacci_recursive(b: &mut Bencher) {
        b.iter(|| {
            let n = test::black_box(20);
            fibonacci_recursive(n)
        });
    }

    #[bench]
    fn bench_fibonacci_imperative(b: &mut Bencher) {
        b.iter(|| {
            let n = test::black_box(20);
            fibonacci_imperative(n)
        });
    }
}

我知道递归实现通常比命令式实现慢,特别是因为Rust不支持尾递归优化(这个实现无论如何都不能使用)。但我并没有预料到以下两次相差近2000次:

代码语言:javascript
复制
running 2 tests
test tests::bench_fibonacci_imperative ... bench:          15 ns/iter (+/- 3)
test tests::bench_fibonacci_recursive  ... bench:      28,435 ns/iter (+/- 1,114)

我使用最新的锈色夜间编译器(rustc 1.25.0-nightly)在Windows和Ubuntu上运行了它,并获得了类似的结果。

这个速度差正常吗?我写错什么了吗?还是我的基准有缺陷?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-01 15:15:32

正如Shepmaster所说的,您应该使用累加器来保持先前计算的fib(n - 1)fib(n - 2),否则您将继续计算相同的值:

代码语言:javascript
复制
pub fn fibonacci_recursive(n: u32) -> u32 {
    fn inner(n: u32, penultimate: u32, last: u32) -> u32 {
        match n {
            0 => penultimate,
            1 => last,
            _ => inner(n - 1, last, penultimate + last),
        }
    }
    inner(n, 0, 1)
}

fn main() {
    assert_eq!(fibonacci_recursive(0), 0);
    assert_eq!(fibonacci_recursive(1), 1);
    assert_eq!(fibonacci_recursive(2), 1);
    assert_eq!(fibonacci_recursive(20), 6765);
}

last等同于fib(n - 1)

penultimate等同于fib(n - 2)

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49052327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档