|
33 | 33 | "from functools import wraps\n", |
34 | 34 | "import string,time\n", |
35 | 35 | "from contextlib import contextmanager,ExitStack\n", |
36 | | - "from datetime import datetime, timezone" |
| 36 | + "from datetime import datetime, timezone\n", |
| 37 | + "from time import sleep,time,perf_counter" |
37 | 38 | ] |
38 | 39 | }, |
39 | 40 | { |
|
47 | 48 | "from nbdev.showdoc import *\n", |
48 | 49 | "from fastcore.nb_imports import *\n", |
49 | 50 | "\n", |
50 | | - "from time import sleep\n", |
51 | 51 | "import shutil,tempfile,pickle,random\n", |
52 | 52 | "from dataclasses import dataclass" |
53 | 53 | ] |
|
1727 | 1727 | { |
1728 | 1728 | "data": { |
1729 | 1729 | "text/plain": [ |
1730 | | - "['h', 'g', 'a', 'd', 'b', 'e', 'f', 'c']" |
| 1730 | + "['a', 'h', 'f', 'b', 'c', 'g', 'e', 'd']" |
1731 | 1731 | ] |
1732 | 1732 | }, |
1733 | 1733 | "execution_count": null, |
|
2114 | 2114 | "\n", |
2115 | 2115 | " def __init__(self, store=5, span=60):\n", |
2116 | 2116 | " import collections\n", |
2117 | | - " self.hist,self.span,self.last = collections.deque(maxlen=store),span,time.perf_counter()\n", |
| 2117 | + " self.hist,self.span,self.last = collections.deque(maxlen=store),span,perf_counter()\n", |
2118 | 2118 | " self._reset()\n", |
2119 | 2119 | "\n", |
2120 | 2120 | " def _reset(self): self.start,self.events = self.last,0\n", |
|
2125 | 2125 | " self.hist.append(self.freq)\n", |
2126 | 2126 | " self._reset()\n", |
2127 | 2127 | " self.events +=n\n", |
2128 | | - " self.last = time.perf_counter()\n", |
| 2128 | + " self.last = perf_counter()\n", |
2129 | 2129 | "\n", |
2130 | 2130 | " @property\n", |
2131 | | - " def duration(self): return time.perf_counter()-self.start\n", |
| 2131 | + " def duration(self): return perf_counter()-self.start\n", |
2132 | 2132 | " @property\n", |
2133 | 2133 | " def freq(self): return self.events/self.duration" |
2134 | 2134 | ] |
|
2188 | 2188 | "name": "stdout", |
2189 | 2189 | "output_type": "stream", |
2190 | 2190 | "text": [ |
2191 | | - "Num Events: 3, Freq/sec: 256.2\n", |
2192 | | - "Most recent: ▁▃▇▅▂ 223.9 260.6 307.1 279.5 252.0\n" |
| 2191 | + "Num Events: 3, Freq/sec: 316.2\n", |
| 2192 | + "Most recent: ▇▁▂▃▁ 288.7 227.7 246.5 256.5 217.9\n" |
2193 | 2193 | ] |
2194 | 2194 | } |
2195 | 2195 | ], |
|
2839 | 2839 | "Person(name=\"Bob\")" |
2840 | 2840 | ] |
2841 | 2841 | }, |
| 2842 | + { |
| 2843 | + "cell_type": "code", |
| 2844 | + "execution_count": null, |
| 2845 | + "metadata": {}, |
| 2846 | + "outputs": [], |
| 2847 | + "source": [ |
| 2848 | + "from functools import wraps\n", |
| 2849 | + "from time import time" |
| 2850 | + ] |
| 2851 | + }, |
| 2852 | + { |
| 2853 | + "cell_type": "code", |
| 2854 | + "execution_count": null, |
| 2855 | + "metadata": {}, |
| 2856 | + "outputs": [], |
| 2857 | + "source": [ |
| 2858 | + "#| export\n", |
| 2859 | + "def timed_cache(seconds=60, maxsize=128):\n", |
| 2860 | + " \"Like `lru_cache`, but also with time-based eviction\"\n", |
| 2861 | + " def decorator(func):\n", |
| 2862 | + " cache = {}\n", |
| 2863 | + " @wraps(func)\n", |
| 2864 | + " def wrapper(*args, **kwargs):\n", |
| 2865 | + " key = str(args) + str(kwargs)\n", |
| 2866 | + " now = time()\n", |
| 2867 | + " if key in cache:\n", |
| 2868 | + " result, timestamp = cache[key]\n", |
| 2869 | + " if seconds == 0 or now - timestamp < seconds:\n", |
| 2870 | + " cache[key] = cache.pop(key)\n", |
| 2871 | + " return result\n", |
| 2872 | + " del cache[key]\n", |
| 2873 | + " result = func(*args, **kwargs)\n", |
| 2874 | + " cache[key] = (result, now)\n", |
| 2875 | + " if len(cache) > maxsize: cache.pop(next(iter(cache)))\n", |
| 2876 | + " return result\n", |
| 2877 | + " return wrapper\n", |
| 2878 | + " return decorator" |
| 2879 | + ] |
| 2880 | + }, |
| 2881 | + { |
| 2882 | + "cell_type": "code", |
| 2883 | + "execution_count": null, |
| 2884 | + "metadata": {}, |
| 2885 | + "outputs": [], |
| 2886 | + "source": [ |
| 2887 | + "@timed_cache(seconds=0.1, maxsize=2)\n", |
| 2888 | + "def cached_func(x): return x * 2, time()\n", |
| 2889 | + "\n", |
| 2890 | + "# basic caching\n", |
| 2891 | + "result1, time1 = cached_func(2)\n", |
| 2892 | + "test_eq(result1, 4)\n", |
| 2893 | + "sleep(0.01)\n", |
| 2894 | + "result2, time2 = cached_func(2)\n", |
| 2895 | + "test_eq(result2, 4)\n", |
| 2896 | + "test_eq(time1, time2)\n", |
| 2897 | + "\n", |
| 2898 | + "# caching different values\n", |
| 2899 | + "result3, _ = cached_func(3)\n", |
| 2900 | + "test_eq(result3, 6)\n", |
| 2901 | + "\n", |
| 2902 | + "# maxsize\n", |
| 2903 | + "_, time4 = cached_func(4)\n", |
| 2904 | + "_, time2_new = cached_func(2)\n", |
| 2905 | + "test_close(time2, time2_new, eps=0.1)\n", |
| 2906 | + "_, time3_new = cached_func(3)\n", |
| 2907 | + "test_ne(time3_new, time())\n", |
| 2908 | + "\n", |
| 2909 | + "# time expiration\n", |
| 2910 | + "sleep(0.2)\n", |
| 2911 | + "_, time4_new = cached_func(4)\n", |
| 2912 | + "test_ne(time4_new, time())" |
| 2913 | + ] |
| 2914 | + }, |
2842 | 2915 | { |
2843 | 2916 | "cell_type": "markdown", |
2844 | 2917 | "metadata": {}, |
|
0 commit comments