Qt 性能优化:CPU占有率高的现象和解决办法

这篇具有很好参考价值的文章主要介绍了Qt 性能优化:CPU占有率高的现象和解决办法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

在最近的项目中,发现执行 Qt 程序时,有些情况下的 CPU 占用率奇高,最高高达 100%。项目跑在嵌入式板子上,最开始使用 EGLFS 插件,但是由于板子没有单独的鼠标层,导致鼠标移动起来卡顿,很不流畅,所以换成了 LinuxFB 插件。但是如果 CPU 占有率高了的话,也会导致鼠标卡顿,因为鼠标是由 Qt 应用程序层负责绘制的,如果应用程序 CPU 占有率高了的话,也会导致鼠标绘制缓慢,导致鼠标卡顿。

所以要解决 CPU 占有率高的问题,进行性能优化,本文对项目中容易出现的问题现象与解决办法进行了记录。

二、UI 控件频繁刷新

现象

代码逻辑控制的 UI 控件(包括 QWidget)频繁刷新,或者某个动作频繁执行。UI 刷新在一定程度上会对CPU占用率有影响,若频繁刷新控件(不论是重绘还是更新数据),都会十分消耗 CPU 占用率。例如一个时间 Label,采用定时器设置时间,如果定时器的定时间隔过短,比如 10ms 甚至更短,就会比较消耗 CPU 占用率。

解决方法

所以自定义 UI 控件时就需要注意避免频繁刷新;定时器的间隔时间也要合理设置,避免过短或过长。

三、paintEvent 高频绘图

这个情况很常见,但相关内容很多不方便放在这,可以看我的下一篇博客:Qt 性能优化之二:绘制视频方案选择

四、优化界面刷新

现象
项目中有一项功能是在子线程里读数据,数据若发生变化了就发送信号,在槽里更新界面。程序运行的时候会出现数据变化很频繁的情况,也导致更新界面的信号在短时间内被触发很多次,大大损耗了程序的性能。

解决方法
因为人眼捕获的帧率有限,所以界面显示不需要太快的刷新速度,把信号槽更新界面改为用定时器更新界面,就能避免某一时间段数据变化过频导致的卡顿问题。

五、样式表导致绘图事件频繁调用

现象

QWidget:主窗口,背景利用setStyleSheet设置,同时重写paintEvent事件(QWigdet 的 paintEvent 默认为空):

void mainWidget::paintEvent(QPaintEvent *event)
{
    QStylePainter painter(this);
    QStyleOption opt;
    opt.initFrom(this);
    opt.rect = this->rect();
    painter.drawPrimitive(QStyle::PE_Widget,opt);
    QWidget::paintEvent(event);
}

主窗口上有众多不规则按键(某些按键组合成按键组,按下一个按键按键组的外观一起改变,通过设置样式表实现),每个按键都setMask设置有效区域,按键在按下,松开,选中都会有不同的样式,通过setStyleSheet设置。

结果发现,按键在响应过程中非常慢,top 看一下 CPU 占用率在点击按键时达到了 90%+,重绘事件在控件外观发生变化时会被调用。

猜测:在操作按键(按下,松开,点击)时在其槽函数改变按键的样式表,按键为主窗口的子控件。所以也会操作到主窗口的样式表。也即,主窗口的重绘事件也被调用。也就导致了每点击一个按键,最少也要调用三次主窗口的重绘事件。重复多次调用重绘事件使得在嵌入式平台中响应速度变慢。

解决方法

主窗口不使用样式表方式设置背景,改用调色板方式,此时主窗口样式表为空:

mainWidget::mainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::mainWidget)
{
    QPixmap pixmap;
    QPalette palette;
    setWindowFlags(Qt::FramelessWindowHint);
    pixmap.load(":/images/res/mianbackground.png");
    palette.setBrush(QPalette::Window, QBrush(pixmap));
    setPalette(palette);
    ui->setupUi(this);
···
}

此时操作按键,CPU 占用率已经大大减小了,基本不会有超过 10% 的情况。

六、短时间内创建大量控件

现象

如果短时间内创建多个控件,例如一个 10x10 的控件网格,测试发现也会比较消耗 CPU 资源,尤其这个自定义控件本身比较消耗资源的话。

解决方法

  • 优化自定义控件,减少单个控件创建所需的资源;
  • 每创建一个或者一部分控件后,加点 sleep() 延时,但是这样会导致创建控件比较慢,视觉效果也不是很好,看怎么取舍了;
  • 如果是创建大量只需要显示的控件,例如一些图标控件,可以考虑使用 Qt 的图形视图 Graphics View 框架,创建图元比创建 QWidegt 控件快多了,但是需要考虑 QWidget 与 QGraphicsScene 的嵌套使用。

七、短时间内多次调用 qDebug() 打印造成卡顿

现象

如果执行了一个操作,然后短时间内多次调用 qDebug() 打印,测试发现也会比较消耗 CPU 资源。

解决方法

所以平时不要加太多打印,正式发布后一些调试打印要即使删除。如果为了测试方便,有些打印不想删除,可以选择正式版本关闭打印,测试时可以使用终端执行./proName d来运行应用程序以输出打印,d是要输出打印的后缀。代码如下:

// 默认先关闭qDebug()打印,以减少短时间内输出大量qDebug()打印造成的卡顿
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, false);
// 如果执行./proName d,则开放打印
if(QString::fromUtf8(argv[1]) == "d") {
	printf("Open qDebug!!!!!\n");
	QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
}

八、设置线程优先级

现象
项目中有多线程的操作,所有的线程都是用默认的QThread::InheritPriority优先级。因为设备的性能有限,让所有的线程都以高优先级去运行,主线程被过多地占用资源,导致界面刷新卡顿的问题。

解决方法
Qt 的线程提供了以下几种优先级(由低到高排列),按照实际情况去设置优先级,可以提高界面的流畅度。

  • QThread::IdlePriority
  • QThread::LowestPriority
  • QThread::LowPriority
  • QThread::NormalPriority
  • QThread::HighPriority
  • QThread::HighestPriority
  • QThread::TimeCriticalPriority
  • QThread::InheritPriority

九、检查子线程的延时操作

现象
项目里有一个子线程的代码结构是这样的。

void run() {
	while (true) {
		if (...) {
   			continue;
		}
	
		..... //operate
		msleep(20);
	}
}

线程在延时状态下是会把 CPU 交给其它线程的,避免不停地抢占 CPU,以上代码虽然加了延时,但前面有一个判断操作,如果满足了条件,就直接调用continue,如果这个判断条件一直都是满足的,那就会不停地 continue,代码也就变成了以下形式。

void run() {
	while (true) {
   		continue;
	}
}

等同于一个死循环,这样会大大影响程序的效率。

解决方法
在每个 continue 前添加延时。

void run() {
	while (true) {
		if (...) {
			msleep(20);
   			continue;
		}
	
		..... //operate
		msleep(20);
	}
}

或者避免使用 continue:

void run() {
	while (true) {
		if (...) {
			..... //operate
		}
	
		msleep(20);
	}
}

另外多线程,要合理的使用 sleep。对于while(1)中有耗时处理的,添加Sleep(0)就可以;对于没有耗时处理的,添加Sleep(0)就不行了,Sleep(1),Sleep(5)都行。

十、优化数据库查询方式

如果表中数据量大或者查询频率高,可以使用 map 容器来存放,以空间换时间,减少查询损耗。或者调整数据结构,将 2,3 百条数据的数组改成 map 结构储存等等。

十一、通信协议的优化

可以通过优化通信协议来减少客户端和服务端的计算量。

十二、减少不必要的IO操作

IO 操作是比较耗时的,常见的 IO 有通信 IO 和文件 IO,可以检查相关代码进行优化。文章来源地址https://www.toymoban.com/news/detail-402569.html

到了这里,关于Qt 性能优化:CPU占有率高的现象和解决办法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • CPU性能优化——“瑞士军刀“

            最近在做一些工具的预研工作,会涉及到对工具的压力测试,分析工具的资源消耗等问题,其中CPU 资源消耗是关键指标之一。为了后续性能优化做准备,回顾了以前相关CPU优化知识,并做总结分享。希望能帮助到正在遇到相关问题的同事。         cpu 使用率

    2024年02月05日
    浏览(59)
  • CPU和GPU性能优化

    在Unity游戏开发中,优化CPU和GPU的性能是非常重要的,可以提高游戏的运行效率、降低功耗和延迟,并提高用户体验。以下是一些优化CPU和GPU性能的方法: 1.优化游戏逻辑和算法 减少不必要的计算和内存操作,例如避免频繁的分配和释放内存,减少不必要的数据结构和循环。

    2024年02月09日
    浏览(47)
  • RK3588 CPU性能优化

    CPU负载的采样时间关系到CPU的变频和大小核调度的及时性,目前系统的默认配置是32ms,可以通过如下节点获取: 目前的采用时间可以设置为32ms和8ms,在8ms的情况下cpu的负载变频和大小核调度会更及时,但是同时功耗也会对应的增加; 可以通过如下命令进行设置: 如果要在

    2024年02月12日
    浏览(51)
  • Linux性能优化实践——CPU上下文

    Linux是一个多任务操作系统,它支持远大于CPU数量的任务同时运行。这些任务不是真正意义上的并行运行,而是系统在短时间内,将CPU轮流分配给它们,造成任务同时运行的错觉。 CPU需要知道任务从哪里加载,从哪里开始运行是通过设置好的CPU寄存器和程序计数器(Program C

    2024年02月13日
    浏览(58)
  • Android 性能优化 命令行查看CPU使用率

    本文介绍cpu使用率概念,和使用ps命令、top命令和dumpsys cpuinfo命令来查看cpu使用率,帮助我们了解应用程序在运行过程中的整体状态和各个线程状态。 CPU利用率指系统中CPU的使用情况,通常以百分比表示CPU使用率。 在多核情况下,CPU使用率指的是所有核心的平均使用率。 通

    2024年02月05日
    浏览(55)
  • 记1次前端性能优化之CPU使用率

    碰到这样的一个问题,用户反馈页面的图表一直加载不出来,页面还卡死 打开链接页面,打开控制台 Network 看到有个请求一直pending,结合用户描述,页面一直loading,似乎验证了我的怀疑:后端迟迟没有相应。 但是,还有个现象,页面卡死了,后端没响应怎么能导致页面卡死

    2024年02月10日
    浏览(48)
  • 性能优化-内存泄漏、内存溢出、cpu占用高、死锁、栈溢出详解

    含义:内层泄露是程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费。(换言之,GC回收不了这些不再被使用的对象,这些对象的生命周期太长) 危害:当应用程序长时间连续运行时,会导致严重的性能下降;OOM;偶尔会耗尽连接对象;可

    2024年01月19日
    浏览(65)
  • 【C/C++ 性能优化】了解cpu 从而进行C++ 高效编程

    在当代软件开发领域,CPU(Central Processing Unit,中央处理器)的性能优化一直是一个核心议题。尤其是对于C++开发者而言,无论是在Linux平台还是其他操作系统中,都需要深刻理解CPU的工作原理以及如何充分利用CPU资源,以确保软件运行的高效性和稳定性。正如计算机科学家

    2024年02月20日
    浏览(102)
  • 计算机体系结构之CPU的构建和性能优化(个人学习)

    计算机体系结构是计算机科学中一门关键的领域,而其中的中央处理单元(CPU)更是整个计算机系统的心脏。CPU的构建与性能优化直接影响着计算机的运算速度和效能。随着科技的不断进步,CPU设计也在不断演进,从简单的单核结构到复杂的多核和并行计算,再到涉及超标量

    2024年02月01日
    浏览(61)
  • 【性能优化】CPU利用率飙高与内存飙高问题

    📫作者简介: 小明java问道之路 , 2022年度博客之星全国TOP3 ,专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化,文章内容兼具广度、深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公司后端高级工程师。          📫 热衷分享,喜欢原

    2024年02月05日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包