在计算机科学中,缓存是提高数据访问速度的关键技术。LRU(Least Recently Used)和LFU(Least Frequently Used)是两种常见的缓存替换策略。本文将深入探讨这两种策略的实现细节,并通过实例展示它们的差异。
LRU缓存基于一个核心思想:最近使用的数据很可能在未来也会被使用。因此,当缓存满时,最久未使用的数据会被移除。
实现步骤:
get
和put
操作。代码示例:
class LRUCache {
private Map<Integer, DoubleNode> map;
private DoubleNode head, end;
private int capacity, count;
public LRUCache(int capacity) {
this.capacity = capacity;
map = new HashMap<>();
head = new DoubleNode(-1, -1);
end = new DoubleNode(-1, -1);
head.next = end;
end.prev = head;
}
public int get(int key) {
if (map.get(key) == null) return -1;
DoubleNode node = map.get(key);
moveToHead(node);
return node.val;
}
public void put(int key, int value) {
if (map.get(key) == null) {
DoubleNode node = new DoubleNode(key, value);
if (count >= capacity) {
map.remove(end.prev.key);
linkPreAndNext(end.prev);
count--;
}
map.put(key, node);
moveToHead(node);
count++;
} else {
DoubleNode node = map.get(key);
node.val = value;
moveToHead(node);
}
}
private void moveToHead(DoubleNode node) {
linkPreAndNext(node);
node.prev = head;
node.next = head.next;
head.next.prev = node;
head.next = node;
}
private void linkPreAndNext(DoubleNode node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
}
LFU缓存不仅考虑了数据的使用时间,还考虑了数据的使用频率。当缓存满时,最不经常使用的数据会被移除。
实现步骤:
代码示例:
class LFUCache {
private int capacity, globalTime;
private Map<Integer, Node> map;
private TreeSet<Node> set;
public LFUCache(int capacity) {
this.capacity = capacity;
globalTime = 0;
map = new HashMap<>();
set = new TreeSet<>();
}
public int get(int key) {
if (map.get(key) == null) return -1;
Node cur = map.get(key);
set.remove(cur);
cur.cnt++;
cur.time = globalTime;
globalTime++;
set.add(cur);
map.put(key, cur);
return cur.value;
}
public void put(int key, int value) {
if (map.containsKey(key)) {
Node cur = map.get(key);
set.remove(cur);
cur.value = value;
cur.cnt++;
cur.time = globalTime;
globalTime++;
map.put(key, cur);
set.add(cur);
} else {
if (set.size() >= capacity) {
Node deleteNode = set.first();
set.remove(deleteNode);
map.remove(deleteNode.key);
}
Node cur = new Node(1, globalTime, key, value);
globalTime++;
set.add(cur);
map.put(key, cur);
}
}
class Node implements Comparable<Node> {
int cnt, time, key, value;
public Node(int cnt, int time, int key, int value) {
this.cnt = cnt;
this.time = time;
this.key = key;
this.value = value;
}
public int compareTo(Node other) {
if (cnt == other.cnt) return time - other.time;
else return cnt - other.cnt;
}
}
}
LRU和LFU是两种不同的缓存策略,各有其适用场景。LRU策略简单高效,适用于大多数情况。而LFU策略则考虑了数据的使用频率,更适合处理突发流量和热点数据。在实际应用中,根据具体需求选择合适的策略可以显著提高系统性能。
声明:
1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。
2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。
3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。
4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
Copyright 2005-2024 yuanmayuan.com 【源码园】 版权所有 备案信息
声明: 本站非腾讯QQ官方网站 所有软件和文章来自互联网 如有异议 请与本站联系 本站为非赢利性网站 不接受任何赞助和广告