新人第一次写博客,高手无视即可
公司项目:彩票缩水软件,接触过的朋友可能有了解,四星缩水、五星缩水,四星缩水要处理1W个数即0000到9999 再加上每个数字之间要使用空格隔开即四星缩水要处理5W个字符
五星缩水要处理10W个数字即00000 到 99999,同样加上数字之间的空格符,要处理60W个字符
优化公司其他同写的程序,四星的还好10S左右出结果,五星的我没用他写的程序算出来过结果,感觉没必要等,据他说大概10~20min,
效率如此低有以下两个原因:
1、原始程序应该是用了两个线程,一个线程用来计算,另外一个线程用来刷新程序界面不卡顿,嗯对的,一个线程计算60W个字符,而且这60W字符还要经过大概十几个模块的计算,计算一下 60W*15个模块=900W字符
单个线程计算900W字符
2、部分算法效率低的出奇
效率低的算法集中在三个模块 杀单双、质合、大小这三块,刚来公司试用期时候修改这个项目,简直不忍直视,以及后期优化的大底交集模块。
下面拿大底交集这块为例,说下算法优化以及如何分线程处理:
程序使用了backgroundworker但是却不知道使用begininvoke多开线程使用异步减少计算时间。后期项目找bug改bug期间,我其他项目压着,脱不开都跟这个软件最初的开发人员说如何修改大底交集这块效率高,这块算法写着难度并不大,就是求AB的交集,AB的并集,A排除B,B排除A,
算法难度写着不打,拿AB交集来说,一般的逻辑就是(本人C#,微软死忠粉)
String[] a=A.spilt(‘ ’);(ps:数字与数字之间用的空格键分割)
Foreach(string kkk in a)
{
If(B.indexof(kkk)>-1)
{
将KKK记录下来,因为kkk是a和b共有的
}
}
但是这样的话如果A B中的数少的话还行,单线程计算量也大不到哪里,但是如果A B都是七八W这个级别的数量的话,计算完大概需要30S左右 但是这也是不行的,我的解决方案想了两个,一个就是把A或者B分块,分完之后每一块都与另外一整块比对,但是效率还是不行虽然比单线程的快了一半儿,但仍然不行
之后的方案:分份了,但是还是需要那么长时间,猜测时间长估计是字符串比对消耗时间过长,既然比对字符串时间过长,那么的话就比对int吧,直接申请两个长度是10W的int类型的数组,分别存储A B中的数字遍历A Bint.parse,把转换过的数字存储到相应的第index位。遍历两个数组,大概需要时间是0.05s左右,然后使用begininvoke开N(我开了100)个线程 然后就是数组A 和数组B的index 0~999对比 如果两个index都不等于null就是说明 ab都有这个数字 即ab交集中的一个数组 记录下来,开100个线程同时执行 最终计算时间大概是0.2S左右 A B都是8W多个数字
并行计算在大量数据处理时候的效果明显,c#的begininvoke也很好用
ps:本人普通二本刚刚毕业,参加工作不到俩月,高手看看内心说句(菜逼),就好,如果能帮到某位程序猿朋友,荣幸之至
如有更好的算法或者思路,留下qq,请教探讨