`
大猫汤姆
  • 浏览: 35756 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

java反射的性能问题

阅读更多
yyyhbfl
分享到:
评论
19 楼 qqggcc 2009-05-20  
我cache一下是14倍左右,如果不cache是35倍

setAccessible(true);
好像没有什么作用,对速度没多大影响
18 楼 sdh5724 2008-12-02  
架构决定性能!
17 楼 大猫汤姆 2008-12-02  
fjlyxx 写道

这点是这样的,框架的是为系统结构服务的.如果要性能方面的优势那么不用任何框架开发适合当前需求的应用是最好的.干嘛还要附带这么多对系统性能没有帮助的东西呢?
用C去开发我也认同但是在你系统的业务还不稳定的时候你觉得维护的费用会少吗?
牺牲点性能我觉得是值得的.
在项目的后期让人烦恼的绝对不是性能,性能的不足可以通过很多手段去弥补,但是如果是结构的不足那就是致命的了.

有道理
16 楼 大猫汤姆 2008-12-02  
海底行者 写道

反射这么影响性能,那我们应该摒弃发射?
还是继续发扬?

当然应该发发扬啦,不能因为某个事物有缺点就要摒弃。跟生活一样,三教九流各种人都要有接触,没有完美的,只要能合理的利用资源,小偷也能立大功。呵呵,可能比喻的不太恰当。
换个角度来看反射这个概念,在JAVA中需要有,其它语言中也有需要,比如javascript中无处不有反射,AOP等思想,甚至javascript对这些思想的实现,简化的让人觉查不到(我是这么理解的,也许可以说是JS语言天生的性质)
15 楼 sdh5724 2008-12-01  
现在你用JAVA6测试下, JAVA的代码反射以及经有非常本质的提高了. 应该还是不错的. 但是建议不要过度使用. 目前asm/bcel等包取代反射机制获得了巨大的提高. 如果真有这样的需求, 还是好好看看cglib包的使用. 另外JDK Proxy的是spring主要的缺省处理方式, 因此, 楼上的兄弟理解是不对的. 
14 楼 fjlyxx 2008-12-01  
大猫汤姆 写道
fjlyxx 写道
对SPRING的IOC进行了简单测试,factory.getBean(""),效率很低。
在这里没有说SPRING如何如何,SPRING 粉丝不要误会,只是分析分析


1.不要忘记了在 并不是所以的框架每次申请对象的时候都要进行 创建新对象,不是还有对象缓存吗
2.当对象存在的时候大多是通过接口去调用的 这样借着接口的壳其实用到的不完全是反射了. 只有在拼装DI的时候会反射,而一个无状态的对象 拼装了一次后也就无需再重复拼装了


你说的也有道理。

说实在的,我这种开源的东西不太信任,拿来研究借鉴一下思想。
下面讨论下你说的几点。
1.框架对象缓存:我认为轻量级的对像缓存不能解决性能问题,只能有微小提高。每次创建的都是新对像也没必要缓存,要缓存也应该缓存大对像,有状态的。
2.对象存在的时候,也就是你说的把拼装好的代理对象拿来使用,这个不是线程安全的,所以每次都得使用原型。你说的是JAVA是使用接口调用的,这个确实不是反射,但动态代理也需要每次创建原型对象以保证线程安全。并不是拼装一次就安全了。通过SPRING的配置可以看出。
  SPRING等框架没有使用JAVA相关的API,而是使用动态插入字节码,但我认为这个是因为多年以前JAVA反射性能极低而使用的,所以使用这项技术可以提高代理调用时的速度,但是动态生成字节码的时候是需要创建额外对象来进行的,目前据我的测试使用动态字节码与新版JAVA使用动态代理性能差不多。

所以Spring 还有其它的比如Struts 我认为只适合做传统的企业应用,办公软件,企业内部用一用,或者拿来快速开发,需求经常变化的。真正互联网应用应该是宁静的,高性能的,可以在某个峰点承受高压的。看看SPRING源码中有如此多的同步我就害怕。这些框架大量使用反射,动态修改字节码,我认为这样很乱(而且随着JAVA版本的改变说不定这些开源的字节码工具包也要跟着升级维护),不是JAVA的风格,就像是把C语言当作高级解释性语言来使用一样,倒不如用C语言开发出一套更聪明的解释性语言出来,比如python。


这点是这样的,框架的是为系统结构服务的.如果要性能方面的优势那么不用任何框架开发适合当前需求的应用是最好的.干嘛还要附带这么多对系统性能没有帮助的东西呢?
用C去开发我也认同但是在你系统的业务还不稳定的时候你觉得维护的费用会少吗?
牺牲点性能我觉得是值得的.
在项目的后期让人烦恼的绝对不是性能,性能的不足可以通过很多手段去弥补,但是如果是结构的不足那就是致命的了.
13 楼 netfork 2008-12-01  
各位研究过CGLIB的大侠,请帮我解答一下这个问题吧。
我只有十分了,要不我多给分。

http://www.iteye.com/problems/7876
12 楼 大猫汤姆 2008-12-01  
fjlyxx 写道
对SPRING的IOC进行了简单测试,factory.getBean(""),效率很低。
在这里没有说SPRING如何如何,SPRING 粉丝不要误会,只是分析分析


1.不要忘记了在 并不是所以的框架每次申请对象的时候都要进行 创建新对象,不是还有对象缓存吗
2.当对象存在的时候大多是通过接口去调用的 这样借着接口的壳其实用到的不完全是反射了. 只有在拼装DI的时候会反射,而一个无状态的对象 拼装了一次后也就无需再重复拼装了


你说的也有道理。

说实在的,我这种开源的东西不太信任,拿来研究借鉴一下思想。
下面讨论下你说的几点。
1.框架对象缓存:我认为轻量级的对像缓存不能解决性能问题,只能有微小提高。每次创建的都是新对像也没必要缓存,要缓存也应该缓存大对像,有状态的。
2.对象存在的时候,也就是你说的把拼装好的代理对象拿来使用,这个不是线程安全的,所以每次都得使用原型。你说的是JAVA是使用接口调用的,这个确实不是反射,但动态代理也需要每次创建原型对象以保证线程安全。并不是拼装一次就安全了。通过SPRING的配置可以看出。
  SPRING等框架没有使用JAVA相关的API,而是使用动态插入字节码,但我认为这个是因为多年以前JAVA反射性能极低而使用的,所以使用这项技术可以提高代理调用时的速度,但是动态生成字节码的时候是需要创建额外对象来进行的,目前据我的测试使用动态字节码与新版JAVA使用动态代理性能差不多。

所以Spring 还有其它的比如Struts 我认为只适合做传统的企业应用,办公软件,企业内部用一用,或者拿来快速开发,需求经常变化的。真正互联网应用应该是宁静的,高性能的,可以在某个峰点承受高压的。看看SPRING源码中有如此多的同步我就害怕。这些框架大量使用反射,动态修改字节码,我认为这样很乱(而且随着JAVA版本的改变说不定这些开源的字节码工具包也要跟着升级维护),不是JAVA的风格,就像是把C语言当作高级解释性语言来使用一样,倒不如用C语言开发出一套更聪明的解释性语言出来,比如python。
11 楼 海底行者 2008-12-01  
反射这么影响性能,那我们应该摒弃发射?
还是继续发扬?
10 楼 fjlyxx 2008-12-01  
对SPRING的IOC进行了简单测试,factory.getBean(""),效率很低。
在这里没有说SPRING如何如何,SPRING 粉丝不要误会,只是分析分析


1.不要忘记了在 并不是所以的框架每次申请对象的时候都要进行 创建新对象,不是还有对象缓存吗
2.当对象存在的时候大多是通过接口去调用的 这样借着接口的壳其实用到的不完全是反射了. 只有在拼装DI的时候会反射,而一个无状态的对象 拼装了一次后也就无需再重复拼装了
9 楼 大猫汤姆 2008-11-16  
kaneg 写道

这个蛮误导人的,楼主的意思应该是慢12倍吧

你说的对极了,是慢。
8 楼 kaneg 2008-11-14  
<div class='quote_title'>大猫汤姆 写道</div><div class='quote_div'><p><img src='/images/smiles/icon_idea.gif' alt=''/> 多谢各位高人呀,用了CGLIB后,也就是说现在的调用速度是普通方法调用的12倍左右。<br/><span style='text-decoration: line-through;'>看来反射早已经不再是性能问题了。</span></p>
<p>反射还是有些影响的。</p>
<p> </p>
<p>后来又测了一下,与普通方法调用相比:</p>
<p>发现spring反射代理调用方法与JAVA反射方法直接调用性能差不多,SPRING是400倍以上,JAVA是300倍,</p>
<p>CGLIB代理速度最快 12倍</p>
<p>JAVA去除安全性检查速度其次 14倍</p>
<p> </p>
<p>上面测试结果只是在main函数上测试的,其它情况估计差不太多。</p>
<p> </p>
<p>对SPRING的IOC进行了简单测试,factory.getBean(""),效率很低。</p>
<p>在这里没有说SPRING如何如何,SPRING 粉丝不要误会,只是分析分析</p></div><br/>“调用速度是普通方法调用的12倍”
这个蛮误导人的,楼主的意思应该是慢12倍吧
7 楼 大猫汤姆 2008-11-13  
<p><img src='/images/smiles/icon_idea.gif' alt=''/> 多谢各位高人呀,用了CGLIB后,也就是说现在的调用速度是普通方法调用的12倍左右。<br/><span style='text-decoration: line-through;'>看来反射早已经不再是性能问题了。</span></p>
<p>反射还是有些影响的。</p>
<p> </p>
<p>后来又测了一下,与普通方法调用相比:</p>
<p>发现spring反射代理调用方法与JAVA反射方法直接调用性能差不多,SPRING是400倍以上,JAVA是300倍,</p>
<p>CGLIB代理速度最快 12倍</p>
<p>JAVA去除安全性检查速度其次 14倍</p>
<p> </p>
<p>上面测试结果只是在main函数上测试的,其它情况估计差不太多。</p>
<p> </p>
<p>对SPRING的IOC进行了简单测试,factory.getBean(""),效率很低。</p>
<p>在这里没有说SPRING如何如何,SPRING 粉丝不要误会,只是分析分析</p>
6 楼 大猫汤姆 2008-11-13  
repsihWDX 写道
setAccessible(true);
以后再试试:)
如果还觉得不爽,可以cache类中的方法再试试^_^

取消访问性检查速度快多了
一下子提高了十倍,原来是300多倍,现在是30倍左右
5 楼 repsihWDX 2008-11-13  
setAccessible(true);
以后再试试:)
如果还觉得不爽,可以cache类中的方法再试试^_^
4 楼 大猫汤姆 2008-11-13  
repsihWDX 写道
1.反射性能没那么离谱。。30倍左右。
2.cglib实现了对类的动态字节码生成,用switch方式来轮询内省方法。速度差不多是正常方法掉用时间的2~3倍。
3.java反射如果去掉访问检查速度和cglib后的方法调用耗时基本相同。


是不是你测试的压力比较小?压力小差别是不太大的,我调用了一亿次比较得出来的。

calib我去研究测试一下,看样子用了这个动态字节码技术情况会好很多的
3 楼 repsihWDX 2008-11-13  
1.反射性能没那么离谱。。30倍左右。
2.cglib实现了对类的动态字节码生成,用switch方式来轮询内省方法。速度差不多是正常方法掉用时间的2~3倍。
3.java反射如果去掉访问检查速度和cglib后的方法调用耗时基本相同。
2 楼 javaeyebird 2008-11-13  
大猫汤姆 写道
性能问题。

很多IOC,还有框架都使用反射。
特别是在通过反射调用方法的时候,与普通方法调用的性能相差数百倍(本机测出来是300倍以上)。

反射的确方便了编程,代码更合理更美观。300倍在一般应用上面也算不得什么,不过很多地方都用反射那问题就明显了。IOC用到,AOP用到,HIBERNATE要用也许还有别的。真是进退两难

大家快来谈谈,交流一下

-server模式下,差别没这么大,某个Method对象反复invoke,jvm会进一步优化这个反射
1 楼 guooscar 2008-11-13  
动态字节码生成就好了。

相关推荐

Global site tag (gtag.js) - Google Analytics