一个很好的讨论,可以参见通告的连接……
信里面很多高手进行了分析,感觉很有意思,我也写了一点,搅一搅局,哈哈:
看了大家的讨论,我很感兴趣。下面的成绩如果是相邻的,那说明测试了两次,就是两个毫秒的差值。
讨论Java和.Net感觉比较奇怪的。一直都是J2EE和.Net的对比,这个才是门当户对,他们都是面向应用的。况且需要解决的企业程序算法的量比较小,用到这么多ArrayList其实并不常见。
废话一句,J2EE和.Net经常出现的Web应用中,这里的响应速度才决定很多,Yujie引用的那段话说得很公平,因为社区里的人都会维护自己社区的利益,没有自己人会说真话,对于他们并不需要那么多性能测试,只需要你用好,因为一个好的J2EE应用和一个差的J2EE应用型能何止相差100倍??!!我坚持认为平台并不能决定一切,而应用的设计和实现质量才会比较强的影响性能。
然后,关于虚拟机,.Net Framwork 1.1 2.0的差距好像比较大,这个需要考虑一下,不过看Yujie的对比MS实现的虚拟机看样子不容乐观。
Balder真是让我崇拜,钻研的很深,而且解释的非常到位,我觉得没法更加深入剖析了。但是利用Native方法的东西用来和受控的代码对比,性能差距就是会很大,尤其是这个数字被放到到那么大的时候。
再提,测试中使用了256MB内存的机器,而WinXP SP1跑JVM绝对会使用大量虚拟内存,WinXP会占用18x内存(乐观情况,一般2xx),因为javaw.exe绝对会变得庞大,调用虚拟内存造成的性能损失就更加非线性了,所以,我下面的测试用了1G内存,基本上保证物理内存。然后,CPU也是个问题,尤其适用P4的时候,我不知道Mobile的里面是否支持HT,如果支持HT的JVM和.Net虚拟机的效率会受到它们被编译的时候的编译器的优化的影响,并且影响很大,所以我测试使用了AMD Athlon XP(@2083Mhz)的机器,减少一些影响。
废话说了一大堆,我下面的测试主要针对程序在JVM里面运行的一些影响因素的评估,并且从这些因素里面我们能够发现这个测试的一些不妥当之处。
讨论Java和.Net感觉比较奇怪的。一直都是J2EE和.Net的对比,这个才是门当户对,他们都是面向应用的。况且需要解决的企业程序算法的量比较小,用到这么多ArrayList其实并不常见。
废话一句,J2EE和.Net经常出现的Web应用中,这里的响应速度才决定很多,Yujie引用的那段话说得很公平,因为社区里的人都会维护自己社区的利益,没有自己人会说真话,对于他们并不需要那么多性能测试,只需要你用好,因为一个好的J2EE应用和一个差的J2EE应用型能何止相差100倍??!!我坚持认为平台并不能决定一切,而应用的设计和实现质量才会比较强的影响性能。
然后,关于虚拟机,.Net Framwork 1.1 2.0的差距好像比较大,这个需要考虑一下,不过看Yujie的对比MS实现的虚拟机看样子不容乐观。
Balder真是让我崇拜,钻研的很深,而且解释的非常到位,我觉得没法更加深入剖析了。但是利用Native方法的东西用来和受控的代码对比,性能差距就是会很大,尤其是这个数字被放到到那么大的时候。
再提,测试中使用了256MB内存的机器,而WinXP SP1跑JVM绝对会使用大量虚拟内存,WinXP会占用18x内存(乐观情况,一般2xx),因为javaw.exe绝对会变得庞大,调用虚拟内存造成的性能损失就更加非线性了,所以,我下面的测试用了1G内存,基本上保证物理内存。然后,CPU也是个问题,尤其适用P4的时候,我不知道Mobile的里面是否支持HT,如果支持HT的JVM和.Net虚拟机的效率会受到它们被编译的时候的编译器的优化的影响,并且影响很大,所以我测试使用了AMD Athlon XP(@2083Mhz)的机器,减少一些影响。
废话说了一大堆,我下面的测试主要针对程序在JVM里面运行的一些影响因素的评估,并且从这些因素里面我们能够发现这个测试的一些不妥当之处。
Balder原始程序:
首先验证一下程序在JRE 1.5(5.0)和1.4.2里面的差别。
JRE 5.0
36657ms
36953ms
首先验证一下程序在JRE 1.5(5.0)和1.4.2里面的差别。
JRE 5.0
36657ms
36953ms
JRE 1.4.2
32531ms
34140ms
发现性能居然是1.4.2更好,个人认为也许是5.0 JVM里面对资源利用的一些优化造成的吧,5.0利用资源比较小气,嘿嘿。同时这里提出一个问题,这个测试没有考虑内存占用的问题,因为JVM和.Net虚拟机(CLR?)对物理内存的利用不一定一样的,JVM吃内存是非常有名的,所以更多物理内存带来的效率提升需要考虑进去,还有就是CPU资源的利用,他们在运行的时候到底用了多少时间片?需要用CPU占有率衡量一下,这个也是没有考虑进来的地方,都是潜在的不公平的地方。
32531ms
34140ms
发现性能居然是1.4.2更好,个人认为也许是5.0 JVM里面对资源利用的一些优化造成的吧,5.0利用资源比较小气,嘿嘿。同时这里提出一个问题,这个测试没有考虑内存占用的问题,因为JVM和.Net虚拟机(CLR?)对物理内存的利用不一定一样的,JVM吃内存是非常有名的,所以更多物理内存带来的效率提升需要考虑进去,还有就是CPU资源的利用,他们在运行的时候到底用了多少时间片?需要用CPU占有率衡量一下,这个也是没有考虑进来的地方,都是潜在的不公平的地方。
去除掉CMovieInfo里面的Math.random()方法。
33593ms
这里random被执行了20000*4次,是最主要的调用random的地方,看来这个的影响并不大。也许是static方法放在虚拟机里面所以对性能影响不大吧。
33593ms
这里random被执行了20000*4次,是最主要的调用random的地方,看来这个的影响并不大。也许是static方法放在虚拟机里面所以对性能影响不大吧。
我把Demo的removeArrayList()里面的删除的random去掉,直接每次删除第1个节点。
75609ms
74859ms
哈哈,这样其实才像个测试,这是一种最坏的情况,每次删除前面的节点,后面的节点就需要蠕动过来,程序彻底没有了random的干扰,并且测试最差情况。这样可以减少随机数产生的测试偏差,而且同时发现Yujie的程序里面random的种子是固定的,这样生成序列应该是固定的(如果是在C语言里面),这对测试不公平。
75609ms
74859ms
哈哈,这样其实才像个测试,这是一种最坏的情况,每次删除前面的节点,后面的节点就需要蠕动过来,程序彻底没有了random的干扰,并且测试最差情况。这样可以减少随机数产生的测试偏差,而且同时发现Yujie的程序里面random的种子是固定的,这样生成序列应该是固定的(如果是在C语言里面),这对测试不公平。
然后,再修改一下,每次删掉ArrayList的尾巴(mylist.remove(mylist.size()-1)),结果让我瞠目结舌!运行几次都是0ms!
0ms
瓦赛,我终于发现看齐来公平的测试后面隐藏的危险,因为移除的位置太重要了,我怀疑只是
移除尾巴的时候编译器和JVM都有特别的优化。
然后,继续测试一下去除尾巴前面那个(mylist.remove(mylist.size()-2))。
16ms
也就是说不会全部优化掉,但是差距绝对是戏剧性的!如果把他们花成曲线那会是什么样子??我觉得有时间我们可以写个用JFreeChart画一个变化的曲线图,估计很有价值。还没有完,我们可以量化一下random()和new对象CMovieInfo所花费的时间,我们保持删除尾巴的操作(mylist.remove(mylist.size()-1)),只是恢复CMovieInfo的代码到最原来的状态,也就是包含那些random()。
16ms
16ms
很稳定,原来random()即使执行了那么多次对性能造成的损失也可以忽略了。
0ms
瓦赛,我终于发现看齐来公平的测试后面隐藏的危险,因为移除的位置太重要了,我怀疑只是
移除尾巴的时候编译器和JVM都有特别的优化。
然后,继续测试一下去除尾巴前面那个(mylist.remove(mylist.size()-2))。
16ms
也就是说不会全部优化掉,但是差距绝对是戏剧性的!如果把他们花成曲线那会是什么样子??我觉得有时间我们可以写个用JFreeChart画一个变化的曲线图,估计很有价值。还没有完,我们可以量化一下random()和new对象CMovieInfo所花费的时间,我们保持删除尾巴的操作(mylist.remove(mylist.size()-1)),只是恢复CMovieInfo的代码到最原来的状态,也就是包含那些random()。
16ms
16ms
很稳定,原来random()即使执行了那么多次对性能造成的损失也可以忽略了。
这里插一句,我在画Wave图的时候发现毫秒不够用,想找个更小的时间单位的实现,但是发现没有,请问哪位知道除了对时间点求平均值的方法外有没有更好的表示时间的小单位?
最后BTW:如果把这个东西整理一下,发个帖子,估计会火得不得了,哈哈:D