这篇写的略为纠结,算法原理、库都是现成的,我就调用了几个函数而已,这有啥好写的?不过想了想,还是可以介绍一下LRU算法的原理及简单的用法。
 
LRU(Least Recently Used,最近最少使用)是一种内存页面置换算法。什么叫内存页面置换?我们知道,相对于内存的速度来讲,磁盘的速度是很慢的。我们需要查询数据的时候,不能每次都跑到磁盘去查,需要在内存里设置一块空间,把一些常用的数据放在这块空间里,以后查的时候就直接在这里查,而不必去磁盘,从而起到“加速”的作用。但是这块空间肯定是远远小于磁盘大小的。那么什么样的数据放在这里才合适呢?当然是常用的数据。那什么样的数据是“常用”的数据呢?这里就有几种策略了。比如最简单FIFO(先进先出),RR(时间片轮转)等等,当然这就是我们最熟悉的队列和堆栈的做法。LRU也是这样一种策略,它的思想是基于这样一种观察和假定:最近经常访问的数据,在所有数据中也是最常访问的。所以,在这样一块空间中,最近被访问过的页面被当做“频繁访问”的,而一直没有被访问过的则被替换出去。这种思想是操作系统存储管理中最常见的方式之一,而目前也被广泛的应用为“缓存”的概念。缓存思想应用的也是相当广泛的,比如寄存器,比如内存,还有网络、数据库、IO等等方面,只要有输入/输出速度不匹配的地方,缓存就可以作为强有力的武器。
 
扯的有点远。接下来讲讲LRU算法的原理吧。假设我们开了可怜的一小块空间作为缓存,只能存5个数,页面编号为0,1,2,3,4。然后需要查询的一串序列为:4,7,0,7,1,0,1,2,1,2,6。那么将会出现如下图所示的情况:
整个查询过程为:
查询4,缓存中不存在,到磁盘中查,并把4放在缓存中;
查询7,类似上面的情况;
查询0,类似上面的情况;
查询7,直接在缓存中查到了,那么7作为“最近”查过的数据,放在最新的位置;
查询1,缓存中不存在,到磁盘中查,并把4放在缓存中;
查询0,直接在缓存中查到了,那么0作为“最近”查过的数据,放在最新的位置;
。。。。。。
后面依此类推。
 
现在大概清楚LRU是个怎样的算法,以及为什么可以作为缓存来使用了吧。这里有一篇文章分析的不错,可以参考一下:图解缓存淘汰算法一之LRU
现在我的项目中需要用到缓存了,可是忘了名字,只记得大概的原理,就去群里问道:我需要这样一个数据结构,查询效率高,类似字典和队列,但最近访问过的数据最后出队,很久没有访问过的数据就先被踢出去。群里大神指点我去看看LRUCache,恍然大悟,就是这个名字!于是百度了一下,结果找到了不少原理和java实现(比如 http://dennis-zane.iteye.com/blog/128278),就是没看到python的。于是到群里请教大神,大神一语中的:pylru。又去百度了一下,果然有这东西!
pylru可以使用pip安装,可以到pypi上查看下载及使用方法:https://pypi.python.org/pypi/pylru/1.0.9  使用起来又炒鸡简单,按某人的话来说就是:你们python真不要脸。
这个库是纯粹用python写的,有兴趣可以看看它的实现。库十分短小精悍,只有几百行代码,注释还占了一多半。
 
测试:
有点啰嗦了,不过这样结果也很清楚。
如果将来涉及到要写缓存了,能想起来这个东西,就是幸运。这也是我们为什么建议掌握一定的算法基础,以及操作系统、体系结构等基础课程的原因:并不是在实践中让你真的去写一个排序算法,写一个缓存,而是当你在某种场合下,能突然意识到:这特么不就是个XXX算法吗,我以前接触过的。比自己吭哧吭哧半天写出来个诡异的数据结构要好的多。
 
本文参考:
1、《现代操作系统》第四章:存储管理:4.4:页面置换算法
3、360图书馆:图解缓存淘汰算法一之LRU :http://www.360doc.com/content/14/0704/09/10504424_391894263.shtml
4、ITEye:LRUCache的java版本实现:http://dennis-zane.iteye.com/blog/128278
5、PyPI:pylru下载及使用:https://pypi.python.org/pypi/pylru/1.0.9

LRU缓存算法与pylru的更多相关文章

  1. 面试挂在了 LRU 缓存算法设计上

    好吧,有人可能觉得我标题党了,但我想告诉你们的是,前阵子面试确实挂在了 RLU 缓存算法的设计上了.当时做题的时候,自己想的太多了,感觉设计一个 LRU(Least recently used) 缓存 ...

  2. 如何用LinkedHashMap实现LRU缓存算法

    阿里巴巴笔试考到了LRU,一激动忘了怎么回事了..准备不充分啊.. 缓存这个东西就是为了提高运行速度的,由于缓存是在寸土寸金的内存里面,不是在硬盘里面,所以容量是很有限的.LRU这个算法就是把最近一次 ...

  3. HashMap+双向链表手写LRU缓存算法/页面置换算法

    import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向 ...

  4. LRU缓存算法 - C++版

    LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法. 实现思路: hashtable + 双向链表 时间复杂度: 插入,查找,删除:O(1) 空间使用 ...

  5. Java 自定义实现 LRU 缓存算法

    背景 LinkedHashMap继承自HashMap,内部提供了一个removeEldestEntry方法,该方法正是实现LRU策略的关键所在,且HashMap内部专门为LinkedHashMap提供 ...

  6. LinkedHashMap实现LRU缓存算法

    LinkedHashMap的get()方法除了返回元素之外还可以把被访问的元素放到链表的底端,这样一来每次顶端的元素就是remove的元素. 构造函数如下: public LinkedHashMap  ...

  7. LRU缓存算法

    http://blog.csdn.net/beiyeqingteng/article/details/7010411 http://blog.csdn.net/wzy_1988/article/det ...

  8. 算法进阶面试题06——实现LFU缓存算法、计算带括号的公式、介绍和实现跳表结构

    接着第四课的内容,主要讲LFU.表达式计算和跳表 第一题 上一题实现了LRU缓存算法,LFU也是一个著名的缓存算法 自行了解之后实现LFU中的set 和 get 要求:两个方法的时间复杂度都为O(1) ...

  9. LRU缓存原理

    LRU(Least Recently Used)  LRU是近期最少使用的算法,它的核心思想是当缓存满时,会优先淘汰那些近期最少使用的缓存对象. 采用LRU算法的缓存有两种:LrhCache和DisL ...

随机推荐

  1. Java入门系列-22-IO流

    File类的使用 Java程序如何访问文件?通过 java.io.File 类 使用File类需要先创建文件对象 File file=new File(String pathname);,创建时在构造 ...

  2. 巧用CheckedTextView完成自定义radiobutton的listview

    因为要用自定义图片的radiobutton的listview,最开始想自己重新写BaseAdapter,重新定义BaseAdapter中的每个list的item.总之android提供了太多方便的控件 ...

  3. MemcacheHelper.cs

    using Memcached.ClientLibrary; using System; using System.Collections.Generic; using System.Linq; us ...

  4. Windows 10 搭建Hadoop平台

    一.环境配置 JDK:1.8. Hadoop下载地址(我选择的是2.7.6版本):https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ ...

  5. Springboot简单整合Rabbit

    两个项目.分别是生产者和消费者项目 .首先引入依赖.两边pom都一样 第一次练习,启动生产者后,再启动消费者,一直报找不到 队列的声明. 后排查发现是  需要现在生产者这边浏览器访问一次生产消息的方法 ...

  6. Oracle查询表名超过长度限制的表

    SELECT T.table_name, LENGTH(TRIM(T.table_name)) FROM user_tables t ORDER BY LENGTH(TRIM(t.table_name ...

  7. 多文件上传CommonsMultipartResolver

    1.CommonsMultipartResolver是spring里面提供的一个上传方式,效率我不知道,但是加入spring容器管理还是很不错的. 2.先看依赖包pom.xml <project ...

  8. 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台

    一. 开发环境 1. 点击此查看并下载需要的 Eclipse IDE for Java EE Developers 开发工具,依赖于java,推荐选用32位   2. 点击此查看并下载需要的 MySQ ...

  9. shell脚本报错 value too great for base

    此错误是shell脚本在计算以0开头的数字时,默认以8进制进行计算,导致在计算08时超过了8进制的范围,报此错误. shell脚本代码如下: #!/bin/bash a= ..} do a=$[$a+ ...

  10. PHP获取当前时间戳

    PHP提供了专门的获取当前时间戳的函数,那就是time()函数.   time()函数获取当前的UNIX时间戳,返回值为从时间戳纪元(格林威治时间1970年1月1日 00:00:00)到当前的秒数.  ...