Java反射性能

Java反射性能

使用反射而不是调用类构造函数创建对象是否会导致显着的性能差异?



有只小跳蛙
浏览 494回答 3
3回答

Helenr

是的-当然。通过反射查找类是,按震级更贵。引文Java反射文档:由于反射涉及动态解析的类型,因此无法执行某些Java虚拟机优化。因此,反射操作的性能比它们的非反射操作要慢,在性能敏感的应用程序中经常调用的代码部分应该避免反射操作。在我的机器上运行SunJRE 6u10时,我在5分钟内完成了一个简单的测试:public&nbsp;class&nbsp;Main&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doRegular(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doReflection(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;doRegular()&nbsp;throws&nbsp;Exception &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;start&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;&nbsp;i<1000000;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;a&nbsp;=&nbsp;new&nbsp;A(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.doSomeThing(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(System.currentTimeMillis()&nbsp;-&nbsp;start); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;doReflection()&nbsp;throws&nbsp;Exception &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;start&nbsp;=&nbsp;System.currentTimeMillis(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;&nbsp;i<1000000;&nbsp;i++) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;a&nbsp;=&nbsp;(A)&nbsp;Class.forName("misc.A").newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.doSomeThing(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(System.currentTimeMillis()&nbsp;-&nbsp;start); &nbsp;&nbsp;&nbsp;&nbsp;}}根据这些结果:35&nbsp;//&nbsp;no&nbsp;reflection465&nbsp;//&nbsp;using&nbsp;reflection请记住,查找和实例化是一起完成的,在某些情况下,查找可以重构,但这只是一个基本示例。即使您只是实例化,您仍然得到了性能上的成功:30&nbsp;//&nbsp;no&nbsp;reflection47&nbsp;//&nbsp;reflection&nbsp;using&nbsp;one&nbsp;lookup,&nbsp;only&nbsp;instantiating再说一次,YMMV。

12345678_0001

是的,慢点。但是记住第一条该死的规则-过早的优化是万恶之源。(好吧,可能和1号绑在一起干)我发誓,如果有人在工作中来问我这个问题,我会在接下来的几个月里非常小心他们的代码。在确定需要优化之前,千万不要进行优化,在此之前,只需编写好的、可读的代码即可。我也不是说写愚蠢的代码。只要想一想最干净的方法,你就可以做到-没有复制和粘贴,等等。(仍然要小心内部循环和使用最适合您需要的集合-忽略这些不是“未优化的”编程,而是“糟糕的”编程)当我听到这样的问题时,我很害怕,但后来我忘记了,每个人都必须自己去学习所有的规则,才能真正得到它。当你花了一个人月的时间来调试某个“优化”的东西之后,你就可以得到它了。编辑:这条线上发生了一件有趣的事。检查#1答案,这是编译器在优化方面有多么强大的一个例子。测试完全无效,因为非反射实例化可以完全排除。上课?永远不要优化,直到你写了一个干净的,整洁的编码解决方案,并证明它是太慢。

喵喵时光机

您可能会发现,JVM正在优化A=新的A()。如果将对象放入数组中,则它们的性能不太好。)以下指纹.new&nbsp;A(),&nbsp;141&nbsp;ns A.class.newInstance(),&nbsp;266&nbsp;nsnew&nbsp;A(),&nbsp;103&nbsp;ns A.class.newInstance(),&nbsp;261&nbsp;nspublic&nbsp;class&nbsp;Run&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;final&nbsp;int&nbsp;RUNS&nbsp;=&nbsp;3000000; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;class&nbsp;A&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doRegular(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doReflection(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doRegular(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;doReflection(); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;doRegular()&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A[]&nbsp;as&nbsp;=&nbsp;new&nbsp;A[RUNS]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;start&nbsp;=&nbsp;System.nanoTime(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;RUNS;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as[i]&nbsp;=&nbsp;new&nbsp;A(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf("new&nbsp;A(),&nbsp;%,d&nbsp;ns%n",&nbsp;(System.nanoTime()&nbsp;-&nbsp;start)/RUNS); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;doReflection()&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A[]&nbsp;as&nbsp;=&nbsp;new&nbsp;A[RUNS]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;start&nbsp;=&nbsp;System.nanoTime(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;RUNS;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as[i]&nbsp;=&nbsp;A.class.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.printf("A.class.newInstance(),&nbsp;%,d&nbsp;ns%n",&nbsp;(System.nanoTime()&nbsp;-&nbsp;start)/RUNS); &nbsp;&nbsp;&nbsp;&nbsp;}}这表明我的机器上的差别大约是150 ns。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java