Qt QCache 使用指南

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"
相关推荐
ShineWinsu19 小时前
对于Qt:QWidget通用属性的解析—上
数据库·qt·microsoft·面试·gui·属性·qwidget
Quz21 小时前
QML 字体度量与文本度量:FontMetrics 与 TextMetrics
qt
Quz21 小时前
QML 字体加载:FontLoader 与 FontInfo
qt
奇树谦1 天前
Qt | 基于 GVCP 协议的 GigE 工业相机 IP 配置工具
数码相机·qt·tcp/ip
扶尔魔ocy2 天前
【qt openGL入门笔记】windows编译MinGW版本的osgearth(2.10.1)
qt·opengl·osg
小王C语言2 天前
Qt常用控件:按钮类控件,普通按键、单选、复选
开发语言·qt
初阳7852 天前
【基于Qt5仿音乐播放器(六)】——细节打磨与总结
qt·1024程序员节
小鱼仙官3 天前
使用Qt封装C/C++ 动态库 用于第三方调用
c语言·c++·qt
扶尔魔ocy3 天前
【QT OpenGL】知识点编目及传送门
qt·opengl·osg
qq_401700413 天前
Qt Modbus 源码剖析:从 QModbusClient 到工业级通信框架
开发语言·qt·系统架构