LRU缓存淘汰算法分析与实现

简介:

概述

记录一下LRU缓存淘汰算法的实现。

原理

LRU(Least recently used,最近最少使用)缓存算法根据数据最近被访问的情况来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

介绍

下图中,介绍了一个缓存空间为5的缓存队列,当访问数据的顺序是:1,2,3,4,5,6,7,6,4,0时空间中数据的变化过程。
这里写图片描述
可以发现:

  1. 当缓存空间未满时,数据一直往新的空间写;
  2. 当缓存满,并且缓存中没有需要访问的数据时,最先进入缓存的数据被淘汰掉;
  3. 当缓存满,并且缓存中有需要访问的数据时,做了一个数据交换,把访问的数据拿出来,其余数据往下压,最后把访问的数据放到顶部
    在这里,可能有疑问,就是把“数据交换”于“数据完全新增和删除”有什么区别呢?答案是性能,前者是移动指针,后者是更新整个内存空间,后者所花费的系统开销远比前者大得多。

实现

看了算法的介绍,我们想到的数据结构就是链表了。

  • 双向链表的数据结构
    /**
     * 双向链表数据结构
     */
    private class NodePair{
        NodePair frontNode;
        NodePair postNode;
        int data;
    }
  • 逆序查找链表
    /**
     * 根据数据逆序查找链表中是否有此节点,有,则把该点提出来,放到current的位置
     * 当匹配到的时候,返回true
     * @param data
     */
    public boolean searchNode(int data){
        boolean flag = false;
        NodePair tempNode = current;
        //不匹配,即没找到,则继续查找
        while(tempNode.frontNode != null || tempNode.data != data){
            tempNode = tempNode.frontNode;
        }
        //这个判读表示匹配到了
        if(tempNode.data == data){
            tempNode.frontNode.postNode = tempNode.postNode;
            tempNode.postNode.frontNode = tempNode.frontNode;
            current = tempNode;
            flag = true;
        }
        
        return flag;
    }
  • 空间满了,并且缓存中没有待访问的数据,删除最下面的节点,再新增一个节点,相当于重新赋值最下面的节点,如图
    这里写图片描述

红线表示,head将要指向倒数第二个点了,即,倒数第二个点要变成现在最底下的点了。

    /**
     * 给head节点重新赋值操作
     * 实现细节是:
     * 0.倒数第二个点(head的下一个点)的frontNode引用指向null
     * 1.给head所指节点重新赋值
     * 2.current节点的frontNode引用指向head
     * 3.把current节点指向head
     * 4.把head指向head的下一个节点(即,倒数第二个点)
     */
    public void resetHeadNode(int data){
        NodePair secondNode = head.postNode;
        
        head.postNode.frontNode = null;
        
        head.data = data;
        head.frontNode = current;
        head.postNode = null;
        
        current.postNode = head;
        
        current = head;
        
        head = secondNode;
    }
  • 缓存满了,查找缓存中是否有待访问数据,有的话,同时把有的数据放到current指针所指位置。
    /**
     * 根据数据逆序查找链表中是否有此节点,有,则把该点提出来,放到current的位置
     * 当匹配到的时候,返回true
     * @param data
     */
    public boolean searchNode(int data){
        boolean flag = false;
        NodePair tempNode = current;
        //不匹配,即没找到,则继续查找
        while(tempNode.frontNode != null || tempNode.data != data){
            tempNode = tempNode.frontNode;
        }
        //这个判读表示匹配到了
        if(tempNode.data == data){
            tempNode.frontNode.postNode = tempNode.postNode;
            tempNode.postNode.frontNode = tempNode.frontNode;
            current = tempNode;
            flag = true;
        }
        
        return flag;
    }
  • 新增节点
    /**
     * 往LRU缓存中插入数据
     * @param data
     */
    public void addNode(int data){
        //缓存未满,不需要删除,直接插入
        if(length <= size){
            NodePair tempNode = new NodePair();
            tempNode.frontNode = current;
            tempNode.postNode = null;
            tempNode.data = data;
            current = tempNode;
            length++;
        }
        //缓存满了,查找缓存中有没有数据
        else{
            if(!searchNode(data)){
                //缓存中没有,需要给head节点重新赋值
                resetHeadNode(data);
            }
        }
    }

LRU算法的缺点

如果有几个不符合“如果数据最近被访问过,那么将来被访问的几率也更高”的规律时,会破坏缓存,导致性能下降。

总结

写算法时,通过画图,写步骤,先产生一个清晰的思路,然后一步步去做实现刚才思考的步骤。

目录
相关文章
|
26天前
|
机器学习/深度学习 人工智能 监控
AI算法分析,智慧城管AI智能识别系统源码
AI视频分析技术应用于智慧城管系统,通过监控摄像头实时识别违法行为,如违规摆摊、垃圾、违章停车等,实现非现场执法和预警。算法平台检测街面秩序(出店、游商、机动车、占道)和市容环境(垃圾、晾晒、垃圾桶、路面不洁、漂浮物、乱堆物料),助力及时处理问题,提升城市管理效率。
AI算法分析,智慧城管AI智能识别系统源码
|
27天前
|
存储 缓存 算法
缓存淘汰策略
缓存淘汰策略
30 0
|
30天前
|
算法
经典控制算法——PID算法原理分析及优化
这篇文章介绍了PID控制算法,这是一种广泛应用的控制策略,具有简单、鲁棒性强的特点。PID通过比例、积分和微分三个部分调整控制量,以减少系统误差。文章提到了在大学智能汽车竞赛中的应用,并详细解释了PID的基本原理和数学表达式。接着,讨论了数字PID的实现,包括位置式、增量式和步进式,以及它们各自的优缺点。最后,文章介绍了PID的优化方法,如积分饱和处理和微分项优化,以及串级PID在电机控制中的应用。整个内容旨在帮助读者理解PID控制的原理和实际运用。
70 1
|
1月前
|
算法 调度
【算法设计与分析】— —基础概念题(one)可作为日常联系或期末复习
【算法设计与分析】— —基础概念题(one)可作为日常联系或期末复习
47 1
|
20天前
|
存储 XML 缓存
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南(一)
【深入浅出Spring原理及实战】「缓存Cache开发系列」带你深入分析Spring所提供的缓存Cache功能的开发实战指南
42 0
|
1天前
|
算法 数据可视化 Python
Python中LARS和Lasso回归之最小角算法Lars分析波士顿住房数据实例
Python中LARS和Lasso回归之最小角算法Lars分析波士顿住房数据实例
|
2天前
|
算法 定位技术 Windows
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
10 4
|
20天前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
26 1
|
24天前
|
算法
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
TOP-K问题和向上调整算法和向下调整算法的时间复杂度问题的分析
17 1
|
27天前
|
算法
PID算法原理分析及优化
这篇文章介绍了PID控制方法,一种广泛应用于机电、冶金等行业的经典控制算法。PID通过比例、积分、微分三个部分调整控制量,以适应系统偏差。文章讨论了比例调节对系统响应的直接影响,积分调节如何消除稳态误差,以及微分调节如何减少超调。还提到了数字PID的实现,包括位置式、增量式和步进式,并探讨了积分饱和和微分项的优化策略。最后,文章简述了串级PID在电机控制中的应用,并强调了PID控制的灵活性和实用性。
38 1