QCache 是什么?
这是 Qt 官方为 LRU 设计的容器,稳定、高效、代码最少。LRU 缓存(Least Recently Used,最近最少使用)是一种常见的缓存淘汰策略,其核心思想是:当缓存空间不足时,优先淘汰最久未被访问的数据项,以保留近期可能再次被使用的数据。
LRU核心原理
- 基于时间局部性原理:最近被访问的数据,在未来短时间内被再次访问的概率较高。
- 维护数据的访问顺序:最近使用的数据放在"前面",最久未使用的放在"后面"。
- 缓存满时,移除尾部(最久未用)的数据,为新数据腾出空间。
常见应用场景
- 浏览器缓存:只保留最近访问的网页资源,自动清理旧内容。
- 操作系统内存管理:保留最近使用的页面,淘汰不活跃页面。
- 数据库查询缓存:缓存最近执行的查询结果,提升响应速度。
- CPU 多级缓存(L1/L2/L3):利用高速缓存减少 CPU 等待时间。
QCache应用示例
cpp
#include <QCoreApplication>
#include <QDateTime>
#include <QDebug>
#include <QCache>
#include <QThread>
qint64 generateTaskId()
{
static qint64 counter = 0;
return (QDateTime::currentMSecsSinceEpoch() << 20) |
((++counter) & 0xFFFFF);
}
struct TaskResult {
bool success;
QString message;
TaskResult(bool s = false, const QString& m = QString())
: success(s), message(m) {}
};
QCache<qint64, TaskResult> m_resultCache(10);
//QCache<qint64, QPair<bool, QString>> m_resultCache2(10);
bool getTaskResult(qint64 taskId, TaskResult &res)
{
TaskResult* result = m_resultCache.object(taskId);
if (!result){
return false;
}
res.success = result->success;
res.message = result->message;
return true;
}
void processTask(qint64 taskId)
{
bool success = QDateTime::currentMSecsSinceEpoch() % 2;
QString temp = QDateTime::currentDateTime().toString("yyyy/MM/dd hh:mm:ss.zzz");
qDebug() << QString("taskId=%1, success=%2, message=%3").arg(taskId).arg(success).arg(temp);
// 插入新任务(自动成为最近使用)
m_resultCache.insert(taskId, new TaskResult(success, temp));
//m_resultCache2.insert(taskId, new QPair<bool, QString>(true, temp));
qDebug() << "Cache size:" << m_resultCache.size();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for (int i = 0; i < 15; ++i) {
qint64 taskId = generateTaskId();
processTask(taskId);
QThread::msleep(10);
}
// 验证淘汰结果
qDebug() << "Final cache count:" << m_resultCache.size() << "-------------------";
for(auto k : m_resultCache.keys()){
TaskResult result;
bool read = getTaskResult(k, result);
qDebug() << QString("read %1, taskId=%2, success=%3, message=%4").arg(read).arg(k).arg(result.success).arg(result.message);
}
return a.exec();
}
执行结果
bash
"taskId=1864600921498976257, success=1, message=2026/05/08 14:33:29.181"
Cache size: 1
"taskId=1864600921530433538, success=1, message=2026/05/08 14:33:29.211"
Cache size: 2
"taskId=1864600921547210755, success=1, message=2026/05/08 14:33:29.227"
Cache size: 3
"taskId=1864600921562939396, success=0, message=2026/05/08 14:33:29.242"
Cache size: 4
"taskId=1864600921580765189, success=1, message=2026/05/08 14:33:29.259"
Cache size: 5
"taskId=1864600921596493830, success=0, message=2026/05/08 14:33:29.274"
Cache size: 6
"taskId=1864600921613271047, success=0, message=2026/05/08 14:33:29.290"
Cache size: 7
"taskId=1864600921628999688, success=1, message=2026/05/08 14:33:29.305"
Cache size: 8
"taskId=1864600921645776905, success=1, message=2026/05/08 14:33:29.321"
Cache size: 9
"taskId=1864600921661505546, success=0, message=2026/05/08 14:33:29.336"
Cache size: 10
"taskId=1864600921678282763, success=0, message=2026/05/08 14:33:29.352"
Cache size: 10
"taskId=1864600921694011404, success=1, message=2026/05/08 14:33:29.367"
Cache size: 10
"taskId=1864600921711837197, success=0, message=2026/05/08 14:33:29.384"
Cache size: 10
"taskId=1864600921727565838, success=1, message=2026/05/08 14:33:29.399"
Cache size: 10
"taskId=1864600921744343055, success=1, message=2026/05/08 14:33:29.415"
Cache size: 10
Final cache count: 10 -------------------
"read 1, taskId=1864600921596493830, success=0, message=2026/05/08 14:33:29.274"
"read 1, taskId=1864600921744343055, success=1, message=2026/05/08 14:33:29.415"
"read 1, taskId=1864600921628999688, success=1, message=2026/05/08 14:33:29.305"
"read 1, taskId=1864600921613271047, success=0, message=2026/05/08 14:33:29.290"
"read 1, taskId=1864600921645776905, success=1, message=2026/05/08 14:33:29.321"
"read 1, taskId=1864600921678282763, success=0, message=2026/05/08 14:33:29.352"
"read 1, taskId=1864600921661505546, success=0, message=2026/05/08 14:33:29.336"
"read 1, taskId=1864600921711837197, success=0, message=2026/05/08 14:33:29.384"
"read 1, taskId=1864600921694011404, success=1, message=2026/05/08 14:33:29.367"
"read 1, taskId=1864600921727565838, success=1, message=2026/05/08 14:33:29.399"