解惑

解己之惑,解人之惑

日:2006年12月5日

深思熟虑后再开始行动

刚才还在沾沾自喜的说条条大路通罗马,就在我洗碗的时候还在考虑几种方案里面到底哪个更好一些,不曾想就是这个洗碗的时候的并行思考完全推翻了刚才的几种方案。那几种方案的一个最大的问题是它的前提不成立,因为我是为了解决性能问题,而解决性能问题最大的前提是找到性能的瓶颈,性能瓶颈最可能出的地方就是被执行次数最多的代码,我们的框架刚好也使用了代码覆盖工具Cobertura,Cobertura的报告中包含了代码行执行的次数,我需要先分析哪些代码执行的次数比较多,然后再想办法进行优化。
其实这个框架执行了很多重复的操作,我明天的主要工作就是根据代码执行的次数报告来决定缓存哪些结果,特别是程序运行中不可能变化的那些部分。

条条大路通罗马

今天在写测试的用例的时候发现框架的一个Bug,CMP在初始化Entity Bean的时候会自动初始化相关的Entity Bean,但是如果是在一对多的情况下,首先使用的如果是一那端的情况下,不会自动的初始化多那一端的Entity Bean,后来添加了代码修正这个问题后,发现原来只要2分钟运行的所有的测试用例要15分钟才能运行完了,跟踪了一下发现是其中一个测试用例所使用的Entity Bean会连带初始化其他十几个Entity Bean,而且其中有几个Entity Bean的初始数据非常的多,每一个都有300条数据,这样要初始化好需要3分钟,而每个test方法都会来这么一次初始化。后来想着加Cache,Entity Bean填充好以后就缓存起来,后面的test方法再需要初始化的时候就直接进行对象拷贝就可以了,但是Entity Bean在使用的时候会修改一些值,这样如果发生变化的话应该从Cache里面清除,而且需要连带清除所有的Entity Bean。原来缓存的是MockEJB动态创建的Proxy对象,所以要进行对象复制不容易,看了MockEJB的源代码本来想自己也创建一个新的Proxy对象进行复制保存,但是工作量比较大,后来想到的解决的办法就是把对象的属性都复制到一个Map里面,主键是属性的名字,值就是对象值,如果值是集合类型,那么要创建一个同样的集合类并发那个集合里面的全部值加进去。

上面是我在公司的时候的解决方案,在写这篇日志的时候,又想到可能的其他方法,例如初始化Entity Bean的时候不初始化相关的其他的Entity Bean,只有在需要的时候才初始化(增加一个BaseGetterAspect,就像其他的Aspect一样);另外就是在发布Entity Bean的时候不初始化所有的Entity Bean实例,只有在需要使用到那个实例的时候再初始化。当然这两个也不是那么简单就可以实现的,明天还要再好好的考虑下哪种最保险最简单。

在遇到一个问题的时候,解决方案是多种多样的,只要你敢想。:)

© 2025 解惑

本主题由Anders Noren提供向上 ↑