Skip to content

Commit 9c597b6

Browse files
committed
2019.1.27 fib 相关 demo 增加
1 parent 050fd17 commit 9c597b6

File tree

5 files changed

+229
-0
lines changed

5 files changed

+229
-0
lines changed

fib/cache.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import pickle
2+
import time
3+
import inspect
4+
import base64
5+
import hashlib
6+
7+
8+
debug = False
9+
10+
11+
def log(s):
12+
if debug:
13+
print(s)
14+
15+
16+
caches = dict()
17+
updated_caches = []
18+
19+
20+
def get_cache(fname):
21+
if fname in caches:
22+
return caches[fname]
23+
try:
24+
with open(fname, "rb") as f:
25+
c = pickle.load(f)
26+
except:
27+
c = dict()
28+
caches[fname] = c
29+
return c
30+
31+
32+
def write_to_cache(fname, obj):
33+
updated_caches.append(fname)
34+
caches[fname] = obj
35+
36+
37+
def cleanup():
38+
for fname in updated_caches:
39+
with open(fname, "wb") as f:
40+
pickle.dump(caches[fname], f)
41+
42+
43+
def get_fn_hash(f):
44+
return base64.b64encode(hashlib.sha1(inspect.getsource(f).encode("utf-8")).digest())
45+
46+
47+
NONE = 0
48+
ARGS = 1
49+
KWARGS = 2
50+
51+
52+
def cache(fname=".cache.pkl", timeout=-1, key=ARGS | KWARGS):
53+
54+
def impl(fn):
55+
load_t = time.time()
56+
c = get_cache(fname)
57+
log("loaded cache in {:.2f}s".format(time.time() - load_t))
58+
59+
def d(*args, **kwargs):
60+
log("checking cache on {}".format(fn.__name__))
61+
if key == ARGS | KWARGS:
62+
k = pickle.dumps((fn.__name__, args, kwargs))
63+
if key == ARGS:
64+
k = pickle.dumps((fn.__name__, args))
65+
if key == KWARGS:
66+
k = pickle.dumps((fn.__name__, kwargs))
67+
if key == NONE:
68+
k = pickle.dumps((fn.__name__))
69+
if k in c:
70+
h, t, to, res = c[k]
71+
if get_fn_hash(fn) == h and (to < 0 or (time.time() - t) < to):
72+
log("cache hit.")
73+
return res
74+
log("cache miss.")
75+
res = fn(*args, **kwargs)
76+
c[k] = (get_fn_hash(fn), time.time(), timeout, res)
77+
save_t = time.time()
78+
write_to_cache(fname, c)
79+
log("saved cache in {:.2f}s".format(time.time() - save_t))
80+
return res
81+
82+
return d
83+
84+
return impl
85+
86+
87+
@cache(timeout=0.2)
88+
def expensive(k):
89+
time.sleep(0.2)
90+
return k
91+
92+
93+
@cache(key=KWARGS)
94+
def expensive2(k, kwarg1=None):
95+
time.sleep(0.2)
96+
return k
97+
98+
99+
def test():
100+
# Test timeout
101+
t = time.time()
102+
v = expensive(1)
103+
assert v == 1
104+
assert time.time() - t > 0.1
105+
t = time.time()
106+
expensive(1)
107+
assert time.time() - t < 0.1
108+
time.sleep(0.3)
109+
t = time.time()
110+
expensive(1)
111+
assert time.time() - t > 0.1
112+
t = time.time()
113+
v = expensive(2)
114+
assert v == 2
115+
assert time.time() - t > 0.1
116+
# Test key=_ annotation
117+
t = time.time()
118+
v = expensive2(2, kwarg1="test")
119+
assert v == 2
120+
assert time.time() - t > 0.1
121+
t = time.time()
122+
v = expensive2(1, kwarg1="test")
123+
assert v == 2
124+
assert time.time() - t < 0.1
125+
t = time.time()
126+
v = expensive2(1, kwarg1="test2")
127+
assert v == 1
128+
assert time.time() - t > 0.1
129+
cleanup()
130+
print("pass")
131+
132+
133+
if __name__ == "__main__":
134+
test()

fib/cache_fib.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from fib import cache
2+
import time
3+
4+
5+
@cache.cache(timeout=20, fname="my_cache.pkl")
6+
def fib(n):
7+
if n <= 2:
8+
return 1
9+
else:
10+
return fib(n - 1) + fib(n - 2)
11+
12+
13+
if __name__ == "__main__":
14+
x = 47
15+
start = time.time()
16+
res = fib(x)
17+
elapsed = time.time() - start
18+
print("Python Computed fib(%s)=%s in %0.8f seconds" % (x, res, elapsed))

fib/diskcache_fib.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from diskcache import FanoutCache
2+
import time
3+
4+
cache = FanoutCache('/tmp/diskcache/fanoutcache1')
5+
6+
7+
@cache.memoize(typed=True, expire=None, tag='fib')
8+
def fib(n):
9+
if n <= 2:
10+
return 1
11+
else:
12+
return fib(n - 1) + fib(n - 2)
13+
14+
15+
if __name__ == "__main__":
16+
x = 47
17+
start = time.time()
18+
res = fib(x)
19+
elapsed = time.time() - start
20+
print("Python Computed fib(%s)=%s in %0.8f seconds" % (x, res, elapsed))

fib/fib.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import time
2+
3+
4+
def fib(n):
5+
if n <= 2:
6+
return 1
7+
else:
8+
return fib(n - 1) + fib(n - 2)
9+
10+
11+
def cache_fib(n, _cache={}):
12+
13+
if n in _cache:
14+
return _cache[n]
15+
elif n > 1:
16+
return _cache.setdefault(n, cache_fib(n-1) + cache_fib(n-2))
17+
return n
18+
19+
20+
def pow_fib(n):
21+
return pow(2 << n, n + 1, (4 << 2 * n) - (2 << n) - 1) % (2 << n)
22+
23+
24+
def ab_fib(n):
25+
a, b = 1, 1
26+
n = n-2
27+
for i in range(n):
28+
a, b = b, a+b
29+
return b
30+
31+
32+
if __name__ == "__main__":
33+
x = 47
34+
start = time.time()
35+
res = cache_fib(x)
36+
elapsed = time.time() - start
37+
print("Python Computed fib(%s)=%s in %0.8f seconds" % (x, res, elapsed))

fib/lru_fib.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import time
2+
from functools import lru_cache
3+
4+
5+
@lru_cache(maxsize=None)
6+
def fib(n):
7+
if n <= 2:
8+
return 1
9+
else:
10+
return fib(n - 1) + fib(n - 2)
11+
12+
13+
if __name__ == "__main__":
14+
x = 47
15+
start = time.time()
16+
res = fib(x)
17+
elapsed = time.time() - start
18+
print("Python Computed fib(%s)=%s in %0.8f seconds" % (x, res, elapsed))
19+
print(fib.cache_info())
20+

0 commit comments

Comments
 (0)