项目总结(1)——优化指标显示界面

针对客户生产环境中因高频率指标更新导致界面卡顿的问题,通过降低通知频率及减少刷新节点数量进行优化,最终将刷新算法复杂度从O(n)降至O(1)。

一、出现了什么问题

原先的刷新逻辑是:当有指标更新通知到达时,就刷新该指标节点所在树的所有节点,客户的生产环境的更新频率好象是200指标每秒,指标节点数应该会有几千个,一打开界面就直接卡死。

现在优化需求主要为两个:

1、性能需求:解决卡死问题。
2、功能需求:父节点要根据所有子节点的最高级别改变颜色,例如子节点中有严重级别,那么它的所有父辈节点都需要变成对应的红色。

二、我的思路

卡死的根本原因是频繁刷新界面,造成它的原因,一个是服务端更新通知太频繁,一个是客户端更新粒度太大,所以处理这个问题,我从两个方向入手:

1、降低通知频率。
2、减少刷新节点个数。

第1个问题很好解决,把原先「单个节点更新就立刻发送通知」的模式,加一个缓存,改为「定时发送时间段内产生的通知」的模式,每秒更新频率立马就下来了。

第2个问题就复杂一点了,我一共优化了两次。

第一次优化

系统预设级别一共有8种,从正常0到严重7,汇总期间涉及大量的并集运算,我很自然的想到使用二进制位表示子节点的某级别是否存在,如「10000001」表示子节点级别有严重和正常,这样可以利用或运算实现多个节点的级别汇总,遍历一遍就可以得到子节点的最高级别了。

原来的刷新逻辑造成很多不必要的刷新,例如一个父节点下面已经有一个严重的子节点了,那么它的其余子节点再怎么更新,这个父节点都是严重级别,所以我的优化思路是:

1、自底向上更新。
2、更新期间判断节点级别是否发生改变。

所以,刷新的流程大概是这样:

1、节点A级别更新。
2、找到A的父节点FA,汇总FA的所有子节点的级别,并求出最高级别NewMaxLevel。
3、NewMaxLevel与FA的级别比较,如果一样,更新停止,如果不一样,就令A=FA,回到步骤1。

多了一个判断过程,使得可以减少很多的不必要的刷新。

第二次优化

完成第一次优化后,我发现方案还存在优化空间:上述流程的热点代码集中在步骤2(因为涉及树的遍历),如果某FA下有几百几千个指标,那么有可能出现汇总了半天结果发现最高级别没有改变的糟糕情形。

其实父节点根本不需要知道究竟哪个子节点是正常,哪个子节点是严重,它只需要知道所有的子节点的最高级,其实也就是每个级别的节点究竟有多少个。转变了问题方向,那么解决就容易了。我在节点里面加了2个数据,它们的功能分别是

1、记录每个级别的子节点的计数。
2、保存上一次的级别状态,用于更新后减少父节点的计数。

这样,当子节点更新时,只会修改父节点中的计数,而不是让父节点又统计一遍。此时的刷新流程修改成这样:

1、节点A级别更新,记录下OldLevel和NewLevel。
2、找到A的父节点FA,OldLevel对应的计数-1,NewLevel对应的+1,求FA的最高级别NewMaxLevel。
3、NewMaxLevel与FA的OldMaxLevel比较,如果一样,更新停止,如果不一样,就令A=FA,回到步骤1。

后记

至此,是我对这个项目的优化方案。原先的刷新算法复杂度应该是O(n)(n是子节点个数),优化后的是O(1),不涉及遍历,只与整个树的高度有关。

转载于:https://www.cnblogs.com/hiyujie/p/xiang-mu-zong-jieyou-hua-zhi-biao-xian-shi-jie-mia.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值