栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Qt关于Model/View大数据量性能测试

Qt关于Model/View大数据量性能测试

Qt关于Model/View大数据量性能测试
  • 引言
  • 测试思路
  • 测试结果
  • 测试中所遇问题
  • 测试代码

引言

项目中大量使用了设备树,代码是通过Model/View实现的。当设备数量达到1w+时,主界面出现明显卡顿,十有八九是代码实现问题,但在这之前需要先验证Model/View框架的性能,确保重构的基础是牢靠的。

测试思路

依项目需要,测试的model大小应远大于1w+且考虑树形结构,目前设置为10w的初始节点,每个初始节点下再挂上5个子节点,也就是总量为60w。

为模拟设备变化情况,设置了定时器每个1s中随机生成一类事件(添加、修改、删除),同时随机生成一个目标节点,“添加”需要成为该节点的子节点,“修改”需要改变该节点的文字及背景颜色,“删除”则删除该节点。

测试结果

对上述环节的时间分别进行打印,结果如下:

上图中“init time”时间为数据初始化时间,耗时11s。添加、删除、修改分别为“add item time”、“modify item time”、“delete item time”,可见这些操作的耗时是随机的,取决于查找节点的时间,节点越靠前耗时越少。那么我们需要找到最大耗时也就是遍历所有的时间进行估算,可以从图中看到有一个“parent name:root”的打印,这是代码中生成的随机节点不在当前model中的标志,这就意味着查找函数需要遍历全部节点,该次操作的耗时为最长耗时,按照正态分布,该值的中间值0.1s可以近似认为是平均耗时。

上述数据为60w节点的数据,相当于实际项目60倍左右,所以远远高于项目的需求。

测试中所遇问题

测试过程中遇到了QTreeView浏览节点卡顿的问题,而且随着所展示行数的增加,卡顿的现象明显加强。经过搜索得知,需要增加如下代码:

m_treeView->setUniformRowHeights(true);

需要设置为统一的行号,否则qt代码中会不断查询当前所展示行的行高,导致浏览的过程异常卡顿。

测试代码
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    void showEvent(QShowEvent* event) Q_DECL_OVERRIDE;

private slots:
    void slot_timeout();

private:
    void initModel();
    int creatItemID();
    QStandardItem* findItemByID(int id);
    void randomAdd(int randomID);
    void randomModify(int randomID);
    void randomDelete(int randomID);
    QString parentName(QStandardItem* item);

private:
    class QTreeView* m_treeView;
    class QStandardItemModel* m_model;
    class QTimer* m_timer;

    int m_count;
    int m_subCount;
    int m_itemID;
    int m_interval;
};
#include 
#include 
#include 
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_count(100000)
    , m_subCount(5)
    , m_itemID(0)
    , m_interval(1000)
{
    ui->setupUi(this);

    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this, &MainWindow::slot_timeout);

    m_model = new QStandardItemModel(this);

    m_treeView = new QTreeView(this);
    m_treeView->setModel(m_model);
    m_treeView->header()->hide();
    m_treeView->setUniformRowHeights(true);

    setCentralWidget(m_treeView);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showEvent(QShowEvent *)
{
    initModel();
    m_timer->start(m_interval);
}

void MainWindow::slot_timeout()
{
    int randomType = QRandomGenerator::global()->bounded(0, 3);
    int randomIndex = QRandomGenerator::global()->bounded(m_itemID);
    if(randomType == 1){
        randomModify(randomIndex);
    }
    else if(randomType == 2){
        randomDelete(randomIndex);
    }
    else{
        randomAdd(randomIndex);
    }
}

void MainWindow::initModel()
{
    QTime time;
    time.start();

    for (int i=0; isetText(QString::number(i));
        tmpItem->setData(creatItemID());
        for (int j=0; jsetText(tmpItem->text() + "_" + QString::number(j));
            subItem->setData(creatItemID());
            tmpItem->appendRow(subItem);
        }
        m_model->appendRow(tmpItem);
    }

    qDebug() << "init time:" <match(m_model->index(0,0), Qt::UserRole + 1, id, 1, Qt::MatchRecursive);
    if(!indexList.isEmpty()){
        qDebug() << "found, ID:" << id;
        return m_model->itemFromIndex(indexList.first());
    }
    qDebug() << "not found, ID:" << id;
    return nullptr;
}

void MainWindow::randomAdd(int randomID)
{
    QTime time;
    time.start();


    auto item = new QStandardItem();
    item->setText(QDateTime::currentDateTime().toString("MM:ss.zzz"));
    item->setData(creatItemID());

    auto parentItem = findItemByID(randomID);
    if(parentItem == nullptr){
        m_model->appendRow(item);
    }else{
        parentItem->appendRow(item);
    }

    qDebug()<< "add row:" << item->row() << "parent name:" << parentName(item);
    qDebug()<< "add item time:" << time.elapsed()/1000.0<<"s";
}

void MainWindow::randomModify(int randomID)
{
    QTime time;
    time.start();

    auto item = findItemByID(randomID);
    if(item != nullptr){
        qDebug()<< "modify row:" << item->row() << "parent name:" << parentName(item);
        item->setText(item->text() + "_modify");
        item->setData(QVariant(QColor(237,100,100,180)),Qt::BackgroundRole);

    }

    qDebug()<< "modify item time:" << time.elapsed()/1000.0<<"s";
}

void MainWindow::randomDelete(int randomID)
{
    QTime time;
    time.start();

    auto item = findItemByID(randomID);
    if(item != nullptr){
        qDebug()<< "delete row:" << item->row() << "parent name:" << parentName(item);
        auto parent = item->parent() ? item->parent() : m_model->invisibleRootItem();
        parent->removeRow(item->row());
    }

    qDebug()<< "delete item time:" << time.elapsed()/1000.0<<"s";
}

QString MainWindow::parentName(QStandardItem *item)
{
    auto parentItem = item->parent();
    if(parentItem == nullptr){
        return "root";
    }
    else{
        return parentItem->text();
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/350654.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号