函数返回值缓存是优化一个函数的常用手段。我们可以将函数、输入参数、返回值全部保存起来,当下次以同样的参数调用这个函数时,直接使用存储的结果作为返回(不需要重新计算)。

函数缓存允许我们将一个函数对于给定参数的返回值缓存起来。当一个I/O密集的函数被频繁使用相同的参数调用的时候,函数缓存可以节约时间。
 

Python 3.2及以后版本

我们来实现一个斐波那契计算器,并使用lru_cache。

from functools import lru_cache

@lru_cache(maxsize=32)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2) >>> print([fib(n) for n in range(10)])
# Output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] # 我们也可以轻松地对返回值清空缓存,通过这样:
fib.cache_clear()
那个maxsize参数是告诉lru_cache,最多缓存最近多少个返回值。
functools模块和cachetools模块都提供了类似的缓存机制。 
functools提供了lru_cache,如果缓存数据超出参数maxsize的值,就用LRU(最少最近使用算法)清除最近很少使用过的缓存结果

而cachetools模块提供了更多缓存失效策略:

  • LFUCache(Least Frequently Used (LFU) cache implementation.)
  • LRUCache(Least Recently Used (LRU) cache implementation.)
  • RRCache(Random Replacement (RR) cache implementation.)
  • TTLCache(LRU Cache implementation with per-item time-to-live (TTL) value.)

Python 2系列版本

你可以创建任意种类的缓存机制,有若干种方式来达到相同的效果,这完全取决于你的需要。
这里是一个一般的缓存:

from functools import wraps

def memorize(function):
memo = {}
@wraps(function)
def wrapper(*args):
if args in memo:
return memo[args]
else:
rv = function(*args)
memo[args] = rv
return rv
return wrapper @memorize
def fibonacci(n):
if n < 2: return n
return fibonacci(n - 1) + fibonacci(n - 2) fibonacci(25)

总结:

函数的缓存是通过闭包实例来实现的,对于每一个被加上cache装饰器的函数,运行时都会被创建一个不同的闭包实例。
参数的缓存是通过闭包实例中引入的哈希表(dict)的key来保存的。
返回值的缓存是通过字典形式保存,键为函数参数,值为函数返回值,。

refer

函数缓存 (Function caching)的更多相关文章

  1. Python函数缓存

    函数缓存 (Function caching) 函数缓存允许我们将一个函数对于给定参数的返回值缓存起来.当一个I/O密集的函数被频繁使用相同的参数调用的时候,函数缓存可以节约时间.在Python 3. ...

  2. jquery的2.0.3版本源码系列(2):21行-94行定义了一些变量和函数 jQuery=function(){}

    2.1.bug通过索引查询 这里的#13335是bug的索引,如何查询呢? 第一步,浏览器地址栏输入"https://bugs.jquery.com/". 第二步,在网页的搜索框里 ...

  3. 函数式编程 - 函数缓存Memoization

    函数式编程风格中有一个"纯函数"的概念,纯函数是一种无副作用的函数,除此之外纯函数还有一个显著的特点:对于同样的输入参数,总是返回同样的结果.在平时的开发过程中,我们也应该尽量把无 ...

  4. 【转】PowerShell 函数(Function)

    转至:http://blog.csdn.net/kk185800961/article/details/49022395 函数基本操作: [plain] view plain copy #创建函数 F ...

  5. C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化

    模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...

  6. ES6---箭头函数()=>{} 与function的区别(转载)

    1.箭头函数与function定义函数的写法: //function function fn(a, b){ return a + b; } //arrow function var foo = (a, ...

  7. 自执行匿名函数: (function() { /* code */ })();

    1,常见格式:(function() { /* code */ })(); 2,解释:包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括 ...

  8. 笔记:IIFE 立即执行的函数表达式 +function ($) { }(window.jQuery);

    在Bootstrap源码(具体请看<Bootstrap源码解析1>)和其他jQuery插件经常看到如下的写法: +function ($) { }(window.jQuery); 这种写法 ...

  9. 方法(method)和函数(function)有什么区别?

    方法(method)和函数(function)有什么区别? 定义和参数区别 函数是独立的功能,与对象无关,需要显示的传递数据 方法与对象和类相关,依赖对象而调用,可以直接处理对象上的数据,也就是隐式传 ...

随机推荐

  1. VBA读写XML文件

    'Write XML file Sub WriteXML(fpa$, fn$) Dim xmlfile As String xmlfile = ThisWorkbook.Path & &quo ...

  2. Linux下四款常见远程工具比较

    摘要:Linux远程可不像Windows下那么方便,主要是连接的速度.显示的画质不能令人满意(延迟.撕裂).本文只是说一下我用过的四款远程工具.Anydesk官网:https://anydesk.co ...

  3. PCL基础

    博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=264 许可 建议每一个文件包含一个描述代码作者的许可,这对于用户了解使用该代 ...

  4. sqliteDOC创建数据库

    上次刚接触SqlLite,不知道怎么创建数据库,现在做下总结: 界面和MYSQL一样,都是CMD界面,但不是在SQLite.exe中创建数据库: 首先还是说一下cmd下sqlite的使用网上已经很多了 ...

  5. js大文件上传

    一般10M以下的文件上传通过设置Web.Config,再用VS自带的FileUpload控件就可以了,但是如果要上传100M甚至1G的文件就不能这样上传了.我这里分享一下我自己开发的一套大文件上传控件 ...

  6. .NET开发辅助工具-ANTS Performance Profiler【转载】

    https://blog.csdn.net/Eye_cng/article/details/50274109

  7. JAVA 基础编程练习题11 【程序 11 求不重复数字】

    11 [程序 11 求不重复数字] 题目:有 1.2.3.4 个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数字都是 1.2.3.4.组成所有的排列后 ...

  8. SpringBoot之解决一对一、多对一、多对多等关联实体在JSON序列化/输出时产生的无限递归死循环问题(infinite recursion)

    前言 这问题着实让人苦不堪言,有必要把它记下了. @JsonBackReference [亲测有效] 1.使用注解@JsonBackReference标记在有关联关系的实体属性上 2.仅导入此注解类有 ...

  9. CentOS8 使用 aliyun 阿里云 镜像站点的方法

    CentOS8现已可使用国内的aliyun阿里云镜像站,方法如下: 用cd命令切换到yum.repos目录,备份原始的3个repo文件:cd /etc/yum.repos.d/sudo cp Cent ...

  10. jenkins打开空白页

    1.登录jenkins报错提示hudson.security.AccessDeniedException 解决: 修改Jenkins_home/config.xml文件里面的一段内容改成如下 < ...