小白教程

 找回密码
 立即注册
查看: 7772|回复: 4

[已解决]为什么递归功能消耗的处理时间比循环多?

[复制链接]

1

主题

2

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2021-5-20 03:38:22 | 显示全部楼层 |阅读模式
为什么递归功能消耗更多的处理时间比循环?
而且,对于处理器来说,这是否繁琐?
  1. def fibonacci(n):
  2.     if n == 0:
  3.         return 0
  4.     elif n == 1:
  5.         return 1
  6.     else:
  7.         return fibonacci(n-1) + fibonacci(n-2)

  8. print fibonacci(40)
复制代码
这个例子需要大约1分钟,但循环只有几毫秒
最佳答案
2021-5-31 11:07:07
我想你的循环写得不完全一样。
递归表示功能调用。功能调用将需要更多的时间和内存,而不仅仅是执行一个循环。但差别并不大。
但是你的程序写的方式,你重写你的工作一遍又一
遍。我猜你的循环不是用那种方式写的缓慢性是由于算法,而不是本质上的递归。
如果向它添加了一个备忘录缓存,它将快速完成。
  1. from functools import lru_cache

  2. @lru_cache
  3. def fibonacci(n):
  4.     if n == 0:
  5.         return 0
  6.     elif n == 1:
  7.         return 1
  8.     else:
  9.         return fibonacci(n-1) + fibonacci(n-2)

  10. print(fibonacci(40))
复制代码
回复

使用道具 举报

0

主题

2

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2021-5-23 06:46:37 | 显示全部楼层
如果向它添加了一个备忘录缓存,它将快速完成。
回复

使用道具 举报

0

主题

2

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2021-5-26 06:53:51 | 显示全部楼层
我运行此代码
  1. def fib(n):
  2.     fib.count += 1
  3.     if n < 2:
  4.         return 1
  5.     else:
  6.         return fib(n-2) + fib(n-1)

  7. fib.count = 0
  8. print(fib(40))
  9. print(fib.count)
复制代码
然后我运行此代码,使用字典保存和重复使用部分结果:
  1. def fib(n):
  2.     fib.count += 1
  3.     a = partial_results.get(n, None)
  4.     if a is None:
  5.         a = fib(n-2) + fib(n-1)
  6.         partial_results[n] = a
  7.     return a

  8. partial_results = {0:0, 1:1}
  9. fib.count = 0
  10. print(fib(40))
  11. print(fib.count)
复制代码
这类似于 Python 使用缓存为您所做的,但扩展了,以便您可以看到该机制。结果是相同的,但纤维功能只被称为79次。如果我要计算多个斐波纳契数字,其中许多可以通过单个调用fib来计算。
因此,原始递归需要更长的时间,因为它正在做一个荒谬的功能调用计算相同的结果一遍又一
遍。
回复

使用道具 举报

0

主题

2

帖子

4

积分

新手上路

Rank: 1

积分
4
发表于 2021-5-27 08:02:03 | 显示全部楼层
从一个非常简单的情况下开始:
fib [4] = fib [3] +
fib [2] fib [4] = (fib [3] = fib [2] + fib [1] ) =
(fib [2] = fib [1] = fib [0] fib [4] = (fib [3] = (fib [2] = fib [1]
= fib [0]) = fib [1]) = (fib [2] = fib [1] = fib [0]) 这是 9 个调用 fib ()。
此代码记录了每个值 n 的调用
次数:
  1. calls = {}

  2. def fib(n):
  3.     calls[n] = calls.get(n, 0) + 1
  4.     if n < 2:
  5.         return 1
  6.     else:
  7.         return fib(n-1) + fib(n-2)
  8. fib(5)
  9. for n, count in calls.items():
  10.     print(f'{n:3d} : {count:5d}')
  11. print('Total', sum(calls.values()))
复制代码
回复

使用道具 举报

1

主题

3

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2021-5-31 11:07:07 | 显示全部楼层 &
我想你的循环写得不完全一样。
递归表示功能调用。功能调用将需要更多的时间和内存,而不仅仅是执行一个循环。但差别并不大。
但是你的程序写的方式,你重写你的工作一遍又一
遍。我猜你的循环不是用那种方式写的缓慢性是由于算法,而不是本质上的递归。
如果向它添加了一个备忘录缓存,它将快速完成。
  1. from functools import lru_cache

  2. @lru_cache
  3. def fibonacci(n):
  4.     if n == 0:
  5.         return 0
  6.     elif n == 1:
  7.         return 1
  8.     else:
  9.         return fibonacci(n-1) + fibonacci(n-2)

  10. print(fibonacci(40))
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|小白教程 ( 粤ICP备20019910号 )

GMT+8, 2024-9-20 12:36 , Processed in 0.029291 second(s), 27 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

快速回复 返回顶部 返回列表