Just found out that comments in 优快云 does not work for me, and others:
https://blog.youkuaiyun.com/qq_33696345/article/details/87894969
https://blog.youkuaiyun.com/tangdou5682/article/details/52351604
no matter how I change my browser window size. I tried Chrome and Firefox. So I post comments as seperate posts.
Anyway, here is the topic for today:
https://blog.youkuaiyun.com/CxsGhost/article/details/104150547
In recursion, This is
F(N) = F(N-1) + F(N-3)
换言之,今年牛数等于去年牛数加上新生牛数(新生牛数 = 去年3岁小牛数量=4年前牛数)
计算机归递是双刃剑,是好消息也是坏消息。
In Python,
def cows(n):
# non cached version
if n < 4:
return n
return cows(n-1) + cows(n-3)
结果是
import cProfile
cProfile.run('print([cows(n) for n in range(40)])')
[0, 1, 2, 3, 4, 6, 9, 13, 19, 28, 41, 60, 88, 129, 189, 277, 406, 595, 872, 1278, 1873, 2745, 4023,
5896, 8641, 12664, 18560, 27201, 39865, 58425, 85626, 125491, 183916, 269542, 395033, 578949, 848491,
1243524, 1822473, 2670964]
7828941 function calls (45 primitive calls) in 1.829 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 1.829 1.829 <string>:1(<listcomp>)
1 0.000 0.000 1.829 1.829 <string>:1(<module>)
7828936/40 1.829 0.000 1.829 0.046 cow.py:5(cows)
1 0.000 0.000 1.829 1.829 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
毛病是这个函数被调用了7828941次。换句话说我们重复计算了很多次。通过缓存我们可以减少这些计算
from functools import lru_cache as cached
@cached(maxsize=None, typed=False)
def cows_c(n):
# cached version
if n < 4:
return n
return cows_c(n-1) + cows_c(n-3)
cProfile.run('print([cows_c(n) for n in range(40)])')
45 function calls in 0.000 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:1(<listcomp>)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
40 0.000 0.000 0.000 0.000 cow.py:13(cows_c)
1 0.000 0.000 0.000 0.000 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {built-in method builtins.print}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
这个想法是很重要的,因为可以沿着这个想法扩充出去发展成很有用的库,比如不用in process缓存,用分布式缓存,再比如加上函数参数的管理形成context computing。
十年前在Python 2上写过一个版本,时间太长了。