From f6ddbc00e93b3d65e16d95404b1607849aada856 Mon Sep 17 00:00:00 2001 From: wangrong Date: Thu, 24 Sep 2026 22:02:57 +0800 Subject: [PATCH] perf: cache external command outputs in disk info gathering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. getDeviceHardInfo() calls smartctl --all, hwinfo --disk, lshw -C disk each twice via different methods, all serial, causing 5-6s delay 2. Add cache members to DeviceStorage so the first method to run a command stores its output; later methods reuse the cached result 3. Cache is per-object (DeviceStorage is created fresh per call), so no stale data risk; smartctl retry logic (-d sat) is preserved Influence: 1. Open disk info dialog and verify all fields display correctly 2. Verify dialog opens significantly faster (target under 3s) 3. Test with SATA, NVMe, and USB disks for field accuracy perf: 缓存外部命令输出以优化磁盘信息获取 1. getDeviceHardInfo() 中 smartctl --all、hwinfo --disk、lshw -C disk 各被重复调用1次且全部串行执行,导致磁盘信息对话框5-6秒延迟 2. 在 DeviceStorage 中增加缓存成员变量,首个执行命令的方法缓存 其输出,后续方法直接复用缓存结果,消除3次重复调用 3. 缓存为对象级(DeviceStorage 每次调用新建),无脏数据风险; smartctl 重试逻辑(-d sat)保持不变 Influence: 1. 打开磁盘信息对话框,验证各字段(型号、接口、转速等)显示正确 2. 验证对话框打开速度明显提升(目标3秒以内) 3. 对 SATA、NVMe、USB 不同类型磁盘测试信息获取准确性 PMS: BUG-327615 --- service/diskoperation/DeviceStorage.cpp | 116 ++++++++++++++---------- service/diskoperation/DeviceStorage.h | 7 ++ 2 files changed, 73 insertions(+), 50 deletions(-) diff --git a/service/diskoperation/DeviceStorage.cpp b/service/diskoperation/DeviceStorage.cpp index 2f04c897..815a3e29 100755 --- a/service/diskoperation/DeviceStorage.cpp +++ b/service/diskoperation/DeviceStorage.cpp @@ -355,17 +355,19 @@ void DeviceStorage::setAttribute(const QMap &mapInfo, const QS bool DeviceStorage::getDiskInfoFromHwinfo(const QString &devicePath) { qDebug() << "Getting disk info from hwinfo for device:" << devicePath; - QString cmd = QString("hwinfo --disk --only %1").arg(devicePath); - QString outPut; - QString error; - if (Utils::executCmd(cmd, outPut, error) != 0) { - qDebug() << "Failed to execute hwinfo command, error:" << error; - return false; + if (!m_hwinfoOutputCached) { + QString cmd = QString("hwinfo --disk --only %1").arg(devicePath); + QString error; + if (Utils::executCmd(cmd, m_cachedHwinfoOutput, error) != 0) { + qDebug() << "Failed to execute hwinfo command, error:" << error; + return false; + } + m_hwinfoOutputCached = true; } QMap mapInfo; - getMapInfoFromInput(outPut, mapInfo); + getMapInfoFromInput(m_cachedHwinfoOutput, mapInfo); setHwinfoInfo(mapInfo); @@ -445,14 +447,17 @@ void DeviceStorage::getMapInfoFromInput(const QString &info, QMap &m bool DeviceStorage::getDiskInfoFromSmartCtl(const QString &devicePath) { qDebug() << "DeviceStorage::getDiskInfoFromSmartCtl BEGIN"; - QString cmd = QString("smartctl --all %1").arg(devicePath); - QString outPut, error; - int exitcode = Utils::executCmd(cmd, outPut, error); + if (!m_smartctlOutputCached) { + QString cmd = QString("smartctl --all %1").arg(devicePath); + QString error; + int exitcode = Utils::executCmd(cmd, m_cachedSmartctlOutput, error); - if (outPut.contains("Please specify device type with the -d option")) { - qDebug() << "need to specify device type"; - cmd = QString("smartctl --all -d sat %1").arg(devicePath); - exitcode = Utils::executCmd(cmd, outPut, error); - } + if (m_cachedSmartctlOutput.contains("Please specify device type with the -d option")) { + qDebug() << "need to specify device type"; + cmd = QString("smartctl --all -d sat %1").arg(devicePath); + exitcode = Utils::executCmd(cmd, m_cachedSmartctlOutput, error); + } - if (exitcode != 0) { - qDebug() << "Failed to execute smartctl command, error:" << error; - return false; + if (exitcode != 0) { + qDebug() << "Failed to execute smartctl command, error:" << error; + return false; + } + m_smartctlOutputCached = true; } QMap mapInfo; - getMapInfoFromSmartctl(mapInfo, outPut); + getMapInfoFromSmartctl(mapInfo, m_cachedSmartctlOutput); addInfoFromSmartctl(mapInfo); @@ -601,22 +609,25 @@ bool DeviceStorage::getDiskInfoFromSmartCtl(const QString &devicePath) void DeviceStorage::getDiskInfoModel(const QString &devicePath, QString &model) { qDebug() << "DeviceStorage::getDiskInfoModel BEGIN"; - QString cmd = QString("smartctl --all %1").arg(devicePath); - QString outPut, error; - int exitcode = Utils::executCmd(cmd, outPut, error); + if (!m_smartctlOutputCached) { + QString cmd = QString("smartctl --all %1").arg(devicePath); + QString error; + int exitcode = Utils::executCmd(cmd, m_cachedSmartctlOutput, error); - if (outPut.contains("Please specify device type with the -d option")) { - qDebug() << "need to specify device type"; - cmd = QString("smartctl --all -d sat %1").arg(devicePath); - exitcode = Utils::executCmd(cmd, outPut, error); - } + if (m_cachedSmartctlOutput.contains("Please specify device type with the -d option")) { + qDebug() << "need to specify device type"; + cmd = QString("smartctl --all -d sat %1").arg(devicePath); + exitcode = Utils::executCmd(cmd, m_cachedSmartctlOutput, error); + } - if (exitcode != 0) { - qDebug() << "Failed to execute smartctl command, error:" << error; - return; + if (exitcode != 0) { + qDebug() << "Failed to execute smartctl command, error:" << error; + return; + } + m_smartctlOutputCached = true; } - QStringList infoList = outPut.split("\n"); + QStringList infoList = m_cachedSmartctlOutput.split("\n"); for (int i = 0; i < infoList.size(); i++) { QString info = infoList[i]; if(info.startsWith("Device Model:") || info.startsWith("Product:") || info.startsWith("Model Number:")){ @@ -626,14 +637,16 @@ void DeviceStorage::getDiskInfoModel(const QString &devicePath, QString &model) } } - cmd = "lshw -C disk"; - exitcode = Utils::executCmd(cmd, outPut, error); - if (exitcode != 0) { - qDebug() << "Failed to execute lshw command, error:" << error; - return; + if (!m_lshwOutputCached) { + QString error; + if (Utils::executCmd("lshw -C disk", m_cachedLshwOutput, error) != 0) { + qDebug() << "Failed to execute lshw command, error:" << error; + return; + } + m_lshwOutputCached = true; } - infoList = outPut.split("*-disk\n"); + infoList = m_cachedLshwOutput.split("*-disk\n"); for (int i =0; i < infoList.size(); i++) { if(infoList[i].contains(devicePath)) { qDebug() << "found devicePath in lshw output"; @@ -759,15 +772,18 @@ void DeviceStorage::getDiskInfoInterface(const QString &devicePath, QString &int if (interface.isEmpty()) { qDebug() << "interface is empty"; - QString cmd = QString("hwinfo --disk --only %1").arg(devicePath); - QString outPut, error; - int exitcode = Utils::executCmd(cmd, outPut, error); - if (exitcode != 0) { - interface = "UnKnow"; - qDebug() << "Failed to execute hwinfo command, error:" << error; - return; + if (!m_hwinfoOutputCached) { + QString cmd = QString("hwinfo --disk --only %1").arg(devicePath); + QString error; + int exitcode = Utils::executCmd(cmd, m_cachedHwinfoOutput, error); + if (exitcode != 0) { + interface = "UnKnow"; + qDebug() << "Failed to execute hwinfo command, error:" << error; + return; + } + m_hwinfoOutputCached = true; } - QStringList outPutList = outPut.split("("); + QStringList outPutList = m_cachedHwinfoOutput.split("("); interface = outPutList[outPutList.size() - 1].split(" ")[0]; } qDebug() << "DeviceStorage::getDiskInfoInterface END"; diff --git a/service/diskoperation/DeviceStorage.h b/service/diskoperation/DeviceStorage.h index e5e8b40b..7b586226 100755 --- a/service/diskoperation/DeviceStorage.h +++ b/service/diskoperation/DeviceStorage.h @@ -40,6 +40,13 @@ class DeviceStorage private: void getMapInfoFromInput(const QString &info, QMap &mapInfo); + QString m_cachedSmartctlOutput; + QString m_cachedHwinfoOutput; + QString m_cachedLshwOutput; + bool m_smartctlOutputCached = false; + bool m_hwinfoOutputCached = false; + bool m_lshwOutputCached = false; + void getMapInfoFromHwinfo(const QString &info, QMap &mapInfo, const QString &ch = QString(": "));