QT项目性能调优小记

时间:2023-03-08 22:35:43

最近的项目用到了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”的功能,使用的代码如下:

 QByteArray msg = xxx

 QString  str;

 foreach (quint8 b, msg)

 {

     str.append(QString().sprintf(“%02X”, b));

 }

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

 QString  buildString(const QByteArray& ba)

 {

 static const char ascii[] = {‘’, ‘’, ‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘’,‘A’,‘B’,‘C’,‘D’,‘E’,‘F’};

 QString buf;

 buf.resize(ba.length() * );

 int i = ;

 foreach (quint8 b, ba)

 {

     buf[i] = ascii[b >> ];

     buf[i + ] =ascii[b & 0xF];

     buf[i + ] = ‘, ’;

     i += ;

 }

 if (i > )

     i –= ;

 buf[i] = ‘\’;

 return buf;

 }

重新运行后,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对象上,参考代码如下:

 QSqlQuery query(db);

 QByteArray data;

 query.prepare(“update table set data = ? where id = ?”);

 query.bindValue(, data);

 query.bindValue(, id);

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

 query.bindValue(, QString(data));

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

5.其他

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

总结

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