思维的乐趣

Enjoy it
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最近做系统优化的一些感受

Posted on 2010-09-15 23:22  szh114  阅读(641)  评论(0编辑  收藏  举报

做系统优化有两个角度,一是优化算法,二是优化代码的写法。

往往优化算法带来的效率提升要远大于优化代码的效果,这个无需多说。但算法的优化就取决于一个人对系统算法的熟悉程度,

假如一个人并不对系统有多熟,然后要对系统做优化(这个做法是不是本来就有点二呀,汗。。。),怎么办呢。

或者说要集中考察系统的执行情况,确定要针对性地解决的问题,而不是全篇通盘考虑所有代码,考虑多处重构的话,

就要用工具:最近使用了dotTrace跟ANTS,两者都可以既跟踪运行时间,又跟踪内存占用,

前期是主要用dotTrace跟踪执行时间,然后用ANTS跟踪内存使用,但后来发现只用ANTS就够了,ANTS的时间跟踪也很强大。

使用工具可以发现系统中哪些方法被调用了最多次,哪些方法占用了最多的时间,然后进行针对性地处理,

我们这次进行的某个操作就是把多次循环中的一些其实相同的计算(因为得到的值实际上是每次都相同的)提到外面去,并且把循环最内层的代码进行重点照顾,尽量用优化的写法,

比如少用中间变量,用Dictionary的key查询代替List<>的遍历(这个操作效果非常明显),等

遗憾的是在一个调用次数千万级别的方法中,有字符串拼接,然后我用 StringBuilder 代替了 String,竟然没有啥效果,执行时间一点都没上去。。。

可能对内存占用有效果,明天去测一下子。

另外,系统优化绝对是要非常熟悉系统的算法,否则就算你用工具定位到最费时,最占内存的地方,也不知道该怎么优化,单是代码层面,优化空间

往往不大。

 

另外有一个问题是DB中的40几张表,在系统中要用,反复查询,但是该表在使用过程中不修改,不变化,因此为了减少DB连接,

首先把它读到内存中用 DataTable存起来,直接从其中查,但还是很费时间,

现在在想办法把每张表用一个自定义的类封装起来,数据用array或者dictionary,list之类的存,因为感觉查DataTable也还是慢

试试看有没有效果,但是也挺麻烦呀,40多张表,并且表一旦发生变化,代码也得跟着变,很麻烦。

可是为了让用户使用效果好,只能开发者自己麻烦了。毕竟,要能把一个小时的仿真时间降到半小时,开发者再麻烦也值。

 

还有,系统在计算最后要序列化一系列东西,这些东西每次算出来都放在内存中,最终导致内存溢出了。。。。。

解决方法是减少序列化的内容,不是必需的就不序列化,不保存了,另外,想办法实时序列化,而不是存在内存中最后再序列化。

在操作过程中发现,大概序列化对象大于180MB以上就会报 Out of memory 异常了。并且,整体内存占用并不高,

我试过不停地分配内存,分配到内存占用率达到2.99G,都不会报错,但是,如果要把一个大对象一次性序列化到内存中的话,很容易就溢出了。

 

在多线程的使用上,我们这个系统需要依次做多次同样的计算过程,这个过程可以同时开多个线程跑,也可以一个线程依次跑,

经过实验发现,开两个线程,然后每结束一个就开一个新的,同时最多只开两个线程时比较合理,这时CPU(所用机器为双核CPU)利用率已经差不多90%多了,如果只开一个的话CPU利用率大概在60%多的样子,效率不高。

而如果开得线程大于2个的话,CPU利用率还是90%多,整体计算时间并没有减少多少,但是内存占用却成倍增大反而影响了用户体验,得不偿失。

当然前提是这些线程都执行的是完全计算密集型的算法,而不是像刷新一下Timer之类的小线程。像后者,开多少都其实无所谓。