zoukankan      html  css  js  c++  java
  • QT项目性能调优小记

    最近的项目用到了QT 5.5,项目在运行过程中出现了一段时间CPU占用率持续25%,并频繁断网的情况,遂决定对项目性能进行优化。

    优化工具也是VS2010自带的性能分析工具,具体的使用方法参见:http://www.cnblogs.com/smark/archive/2011/10/12/2208039.html

    其中可以选择“just my code”过滤出自己编写的代码。

    通过性能分析工具可以找到占用CPU时间较多的函数,然后按照占有时间多少进行优化->再分析->再优化的步骤,多次优化后,将CPU占用率降到了2%以下。下面将对性能优化提升较大的几个优化步骤进行记录:

    1.优化字符串格式化方法。

    项目中有将QByteArray中的二进制数如”123”格式化成”31, 32, 33”的功能,使用的代码如下:

     1 QByteArray msg = xxx
     2 
     3 QString  str;
     4 
     5 foreach (quint8 b, msg)
     6 
     7 {
     8 
     9     str.append(QString().sprintf(“%02X”, b));
    10 
    11 }
    View Code

    当msg中包含6,7w个字符时,在lz酷睿2代i5的机器上,这段代码需要执行4到5s,因为其中的QString会调用new函数6,7w此,对性能影响极大。优化后的代码如下:

     1 QString  buildString(const QByteArray& ba)
     2 
     3 {
     4 
     5 static const char ascii[] = {‘0’, ‘1’, ‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};
     6 
     7 QString buf;
     8 
     9 buf.resize(ba.length() * 3);
    10 
    11 int i = 0;
    12 
    13 foreach (quint8 b, ba)
    14 
    15 {
    16 
    17     buf[i] = ascii[b >> 4];
    18 
    19     buf[i + 1] =ascii[b & 0xF];
    20 
    21     buf[i + 2] = ‘, ’;
    22 
    23  
    24 
    25     i += 3;
    26 
    27 }
    28 
    29 if (i > 0)
    30 
    31     i –= 3;
    32 
    33 buf[i] = ‘0’;
    34 
    35 return buf;
    36 
    37 }
    View Code

    重新运行后,CPU耗时120ms左右,性能提升了几十倍。

    2.优化界面刷新

    在界面功能中有一处表格显示的功能,显示接收到的数据,在原始的代码中,当接收到一条数据,填充到表格上时,就调用一次表格scrollTo方法,当1s接收到2,3百条数据时,就会调用2,3此scrollTo方法,直接导致了界面频繁更新。

    优化的方法是,考虑到人眼的观察能力,将刷新频率即scrollTo的函数调用固定为1s一次,减少了2,3百此的界面重绘,降低了CUP负载。

    3.优化更新时戳功能

    项目中有一处更新时戳的功能,记录某些状态是否已经超时,原始代码中通过QDateTime记录时戳,当数据到来时会调用QDateTime::currentDateTime更新时戳,当有大量数据到来时会频繁更新时戳,通过性能分析发现此处调用总CPU使用率的7%。考虑该时戳只需要统计时间间隔,遂优化后改用time.h中的clock函数打时戳,该函数返回至程序启动的毫秒数。再次进行性能分析显示此处调用降到CPU使用率的0.23%,性能提升明显。

    4.优化数据库操作

    项目中有一处数据库记录update操作,将QByteArray更新到数据库中,程序中使用了QT中的储存过程API,将QByteArray变量绑定到QSqlQuery对象上,参考代码如下:

    1 QSqlQuery query(db);
    2 
    3 QByteArray data;
    4 
    5 query.prepare(“update table set data = ? where id = ?”);
    6 
    7 query.bindValue(0, data);
    8 
    9 query.bindValue(1, id);
    View Code

    其中data中包含6,7w个数据,其中发现程序在query.bindValue(data)上耗时最多,打印日志发现该data中的内容必定为可显示的ascii,遂将代码改为

    1 query.bindValue(0, QString(data));
    View Code

    减少了QByteArray转换成QString的时间。

    5.其他

    其他优化还包括数据结构的调整,包括将2,3百条数据的数组改成map结构储存等。

    总结

    当然对软件的优化还是用遵循相应的原则,比如不要过早优化,在项目的初期以代码的稳定性,可读性,可扩展性为主要目标,只有当代码的性能不能满足需求时再进行适当的优化。因为往往对代码的优化会牺牲以上三个特效,所以在软件开发过程中,经常需要平衡这些特性。

  • 相关阅读:
    invokerequied
    C#如何用正则表达式截取https和带端口的域名
    flex datagrid combox
    java webservice
    Flexlib 控件 http://code.google.com/p/flexlib/
    Git使用
    转:Vim常用命令
    转:oracle连接查询
    Axis2 spring发布WebService
    oracle jdbc example 示例
  • 原文地址:https://www.cnblogs.com/chinese-zmm/p/5544201.html
Copyright © 2011-2022 走看看