单据(合约规划)性能优化总结原创
金蝶云社区-CRU杨少博
CRU杨少博
11人赞赏了该文章 577次浏览 未经作者许可,禁止转载编辑于2021年08月19日 19:57:16

背景:

    周五快下班时,一线实施反应合约规划单据,成本构成单据体输入金额字段后,系统卡住,一次操作要等10s+后才有响应。

    数据量:成本构成单据体有130+行数据(平时正常单据体最多也有10+,看来测试要根据客户实际场景测试,才能更好的以客户为中心【emoji】)

发现问题:

    第一反应就是值改变事件中可能做了比较耗时的操作,打开代码,快速找到成本构成单据体-金额字段的值改变事件

image.png

    隐隐中觉得是这个 "刷新产品构成分录" 的方法可能是性能瓶颈。简单粗暴,先注释这段,然后上测试环境。使用等量级的数据量测试一下。结果确实是这段代码的原因,注释掉后,金额改变事件没有卡顿,很丝滑顺畅。那现在就看看这个方法里面干了什么事情。

        image.png


    这个方法中存在三层for循环嵌套,根据实际数据算一下,(科目139)*(产品6)* (没有楼栋数据) = 834次循环。如果计算逻辑都是在内存中执行循环800+次,那肯定也是毫秒级。因此怀疑可能存在循环查库操作。继续review code排查


第一层循环中的业务代码排查

image.png

image.png


第二层循环中的业务代码排查

image.png

image.png


第三层循环中没有发现查库操作

解决问题:

  1. 将循环查库操作上提至所有循环外

  2. 重构循环中需要查库的方法参数,传入循环前查库的结果集合

验证:

    单据体值改变事件明显变快,但是分录行有130+时,响应时间在1~2s之间,如果用户需要在每行快速录入数据时,每次键入完数据后,还是需要一定的等待时间。


持续优化:

    一般后台代码性能瓶颈都是在数据库,此时如果还在代码层面优化,也可以,但是成本比较高(此处业务代码算法需要全部翻一遍,优化后,如果对性能改进不大将做了无用功。优化完的代码还需要测试投入测试工作。)显然客户等不了这么久。

    改换一种思路,比如业务层面优化。看看这段业务代码干了什么事情,

  1. 单据体每个单元格修改时调用该耗费时间(以下使用“坏方法”表示该耗时的方法)的方法

  2. 坏方法”中主要功能是,根据当前单据体所有行的数据,一系列复杂计算后,将结果设置到另外一个单据体(“B单据体”)中

  3. B单据体”在界面是隐藏的,客户看不到,只有单据审批后,才会被其他单据使用到。


    因此,我们可以将B单据体”的计算过程迁移到“保存”的操作中,不用每次单据体值改变的时候调用。迁移后,单据体录入数据响应时间已经达到毫秒级,保存操作也在2s左后!可以接受!

    

   

总结:

  1. 避免循环查库,循环前,将需要的数据全部查出。

  2. 代码层面性能优化难度变大或者成本变高时,需要转换思路,从业务层面出发,寻找突破点。

  3. 千里之行,积于跬步。日常coding中需要提升owner意识,代码规范一定要遵守。



    ps : 这篇文章写完用了有半个月时间,基本都是晚上加班抽时间写。虽然花了一些时间只分享了一个小小的性能优化案例,但是总算坚持下来了。后续关于工作中的遇到的问题以及解决方案也会陆续更新。

    大家有什么更好的意见或者建议,欢迎交流!






赞 11