33

分享工作中一次优化程序的过程 - 吴先森

 4 years ago
source link: https://www.cnblogs.com/wuyongfu/p/11084196.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

程序应用场景:

年初从总公司交接了一个评分系统,系统大概情况是80w考生,每个考生105条作答数据,作答数据主要是客观题(单选题,多选题,判断题),评分时间大概40分钟左右。

需求:优化代码,提升评分效率,优化之后评分完成在20分钟左右。

已有代码优化逻辑:

1.程序方面:

多线程,通过计算评分的人数,得到需要的线程数量,开启线程分别进行评分

2.查询数据:

成绩表建立自增长Id,查询匹配需要评分的数据用where id> =Start and id< End

3.插入数据:

采用DataTable数据导入到Sql Server,提示评分完成时保存数据效率

详细说一下第二点的逻辑

假设数据库有100w条需要评分的数据,这时通过计算大概得到需要开启25个线程去同时进行评分,也就是说第一个线程去评分数据库Id在  1~40000考生的数据,也就是说去查询数据时,大概查询语句select * from A where Id>=1 and Id<40000这样能够保证查询出来得效率是最高的;

但是这里会有缺陷,如果数据存在删除过在插入肯定数据就不是连续的,也就是

where Id>=1 and Id<40000不能保证查询得到40000条数据,数据库表中存在的Id不一定是从1开始,所以目前这种查询方式是很理想化的。后续这里还需要在这快研究和学习下。

本次优化细节

代码片段1

 756970-20190625173240407-1051206738.png

 756970-20190625173252483-1364747469.png

756970-20190625173257630-66377940.png 

总结:提取线程内查询数据存储到内存中,从而只会查询一次。

代码片段2

 756970-20190625173319438-1345552359.png

 756970-20190625173328140-1561344871.png

总结:修改List集合取一条数据的方式,Where修改成Find,如果还需要在这里提升查询效率可以修改成for循环,但会导致代码可读性会变差。

代码片段3

 756970-20190625173336244-2120393970.png

 756970-20190625173342841-915343008.png

756970-20190625173350501-1578714335.png

756970-20190626082647424-18420882.png

总结:修改DataTable表Select查询方式,先存储到Dictionary中,在通过Key去取对应的数据。

最后通过测试全部完成评分时间大概20分钟左右,也算成功的完成了这个任务,可能还需要在研究研究代码,看能否有其他地方可以改善的。

存在的疑惑:

线程运算占用的电脑Cpu的具体的值?

是否存在最佳线程数量?

电脑Cpu处理能力越强是否也能够提升程序的评分效率?

1.线程里反复查询而且不变的基础数据放到线程外查询存储到变量中

2.List集合的Where查询修改成Find查询,极高的提升查询效率

3.DataTable的Select改用Dictionary<string,DataRow[]>,同样极高的提升查询效率

这次能够站在前人的肩膀上完成这一次代码的优化还有学习到了很多,瑾以写在这片文章分享个人在平时工作中的解决的一些问题,希望这次能够通过分享此篇文章让自己更多的去记录和分享工作中遇到以及解决的问题,提升自己的竞争力。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK