java反射性能测试分析

2019-03-12 09:45|来源: 网络

java有别于其他编程语言而让我着迷的特性有很多,其中最喜欢的是接口设计,他让我们设计的东西具有美感。同样反射也是我比较喜欢的一个特性,他让程序自动运行,动态加载成为了可能,同时也是现在很多流行框架所必不可少的特性,struts,hibernate等都是,spring本身就是基于反射的就更不用说了。细细想来,似乎很少有不涉及到反射的框架。我自己设计框架的时候,开始也都是运用反射,但是越深入却让我越疑惑,反射的效率一直是我设计框架的心病。    
   
   今天在优化    InstantMVC的时候就考虑怎么提高自动封装form的效率,struts是用的commons-beantuils,好像也没人说struts的效率不高,诚然,beanUtils中很多有用方便的特性让反射开发者着迷,但是通过我今天的测试,却发现beanUtils的易用性要付出巨大的性能代价,虽然在现在这个年代,这么点性能不算什么,但是对于我这种执着的人开发执着的框架,还是对性能有种独特的偏好,目前来说InstantMVC中用的是直接的反射简单封装,而InstantORM(我的持久层框架)中用到是自动生成pojo和相应的pojo辅助类来实现动态高效(比直接的反射高效10-20倍)执行Object的方法(一般是get和set),对于InstantMVC的form利用动态生成辅助类有一定的难度,不是说实现难度,而是对于运用该框架的web开发者来说,不够直接。所以还是主要考虑用反射的,废话不说,下面开始今天的测试。    
   
   首先,测试主要有三部分组成,测试创建对象的性能,测试set方法的性能,测试get方法的性能。我没有看过beanUtils的源代码,不过评我的经验想想BeanUtils应该是做了一些性能的优化的,初步猜测是第一次运行缓存Object的相应东东(具体是什么也不知道),所以测试的时候都是从第二次开始,忽略第一次。下面是测试代码(省略了异常抛出。)      
   
     
public class MyBean {
   String name;
   
int age;
   String[] firends;
   
public static void main(String args[]) {
       Object o1
=beanUtilsCreate();
       Object o2
=javaCreate();
       MyBean my
=new MyBean();
       
long a=System.currentTimeMillis();
       
     
       
for(int i=0;i<5000;i++){
           
//47
           
//beanUtilsCreate();
           
//15
           
//javaCreate();
           
//0
           
//manualCreate();
           
           
//235
           
//beanUtilsSet(o1);
           
//40
           
//javaSet(o2);
           
//0
           
//manualSet(my);
           
           
//203
           
//beanUtilsGet(o1);
           
//47
           
//javaGet(o2);
           
//0
           
//manualGet(my);
       }
       
long b=System.currentTimeMillis();
       System.out.println(b
-a);
   }
   
   
   
//===============下面是 beanUtils的方法
   public static Object beanUtilsCreate() {
       Object ob
=ConstructorUtils.invokeConstructor(MyBean.class,null);
       
return ob;
   }
   
public static void beanUtilsSet(Object ob) {
       BeanUtils.setProperty(ob,
"name", "旺旺旺");
   }
   
public static void beanUtilsGet(Object ob) {
       BeanUtils.getProperty(ob,
"name");
   }
   
   
   //    ===============下面是 java自身的直接反射的方法
   public static Object javaCreate() {
       Object ob
=MyBean.class.newInstance();
       
return ob;
   }
   
public static void javaSet(Object ob) {
       Method m
=MyBean.class.getDeclaredMethod("setName", new Class[]{String.class});
       m.invoke(ob,
new Object[]{"旺旺旺"});
   }
   
public static void javaGet(Object ob) {
       Method m
=MyBean.class.getDeclaredMethod("getName", new Class[0]);
       m.invoke(ob,
new Object[0]);
   }
   
   //    ===============下面是 手动的创建对象
   public static MyBean manualCreate(){
       MyBean my
=new MyBean();
       
return my;
   }
   
public static void manualSet(MyBean my){
       my.setName(
"旺旺旺");
   }
   
public static void manualGet(MyBean my){
       my.getName();
   }
   
   
public int getAge() {
       
return age;
   }
   
public void setAge(int age) {
       
this.age = age;
   }
   
public String[] getFirends() {
       
return firends;
   }
   
public void setFirends(String[] firends) {
       
this.firends = firends;
   }
   
public String getName() {
       
return name;
   }
   
public void setName(String name) {
       
this.name = name;
   }
}
   
上面代码首先创建一个MyBean,简单的name和age属性,然后get和set方法,在main方法中首先构建三个类:    
   
Object o1 = beanUtilsCreate();
Object o2
= javaCreate();
MyBean my
= new MyBean();    
为了防止beanUtils内部对第一次做了缓存操作而使测试不准确。    
   
第二次开始连续循环5000次分别测试 Create,set,和get的性能。    
结果显示如下:    
===================================================    
      BeanUtils   java自己反射   手动    
创建:    47          15            0        
set方法   235         40            0    
get方法   203         47            0    
   
===================================================    
jdk 1.6,1G内存,AMD 2600+    
   
   从上面的结果可以看出,BeanUtils的性能确实不怎么样,这样的结果虽然在现代服务器都菜价了的年代,我还是要为struts和spring等基于反射的框架捏一把汗。不知道spring有没有对反射做过优化,不过上次看Ibatis的时候好像他提供了一个配置选项来增强字节码的反射效率,大概就是那种动态创建字节码的技术吧。    
   
本文链接:http://www.656463.com/article/554,转自: http://www.blogjava.net/kingyaoo/archive/2008/06/07/206533.html  

相关问答

更多
  • 得到三类信息.1.构造函数2.属性3.方法
  • Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中(注意是运行时,而非编译时)的 Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。例如,使用它能获得 Java 类中各成员的名称并显示出来,能够通过字符串形式的类名称(包括完整包名)反射性地创建类的实例,能够动态执行类方法等。 JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。 ...
  • ”。这里强调以下内容: (1) 充分准备以下内容:硬件设备、软件环境、网络条件、基础数据 (2) 充分准备测试场景、典型的场景包括操作序列、并发用户数量条件、用例。 该部分包括使用到上述测试方法:性能测试方法、可靠性测试、压力测试、失效恢复测试 2. 规划性能 3. 发现缺陷 这个环节中是交付给用户的主要工作成果。需要多和开发人员作沟通、多次迭代发现问题、根据用户的需求定义与缺陷的涉及范围、制定一个解决缺陷的优先级。由于软件永远有BUG这一真理,所以发现缺陷不是一次就能结束的工作。比较适合作为服务外包。持续 ...
  • 反射弧分析[2022-04-27]

    他们中的任何一个受到破坏都会使完整的反射活动无法发生,如果是感受器,传入神经,和神经中枢被破坏,那么他们产生的效果都相同,都是既无感觉又不会有反应,而若是传出神经和效应器受破坏,那么就是人会有感觉,但是不会产生反应的,懂了吗
  • 性能分析和性能测试完全不同。 性能测试发生在系统级别,各种负载下,并确保您的系统符合其SLA(服务级别协议)。 分析是您在性能测试显示问题时执行的操作。 它可以帮助您识别系统中对性能问题贡献最大的那些部分,并显示您在哪里集中精力。 Profiling and Performance Testing are different things altogether. Performance testing happens at the system level, under varying types of l ...
  • 是的,一点没错。 通过反思查看课程,大大地更昂贵。 引用Java的反思文档 : 因为反射涉及动态解析的类型,所以不能执行某些Java虚拟机优化。 因此,反射操作的性能比其非反射对象的性能更差,并且应该在性能敏感的应用中被频繁地称为代码的部分中避免。 这是一个简单的测试,我在我的机器上5分钟内被黑客攻击,运行Sun JRE 6u10: public class Main { public static void main(String[] args) throws Exception { ...
  • 你可以这样做: public void a(){ // just for testing try { Thread.sleep(1); //OR some for loop to print something } catch (InterruptedException e) { e.printStackTrace(); ...
  • 我相信JMeter Glossary可以解释所有条款。 万一它会消失: No of Sample数 - 执行的样品总数。 Latest sample - 不言自明 Average - 所有采样器执行时间的算术 Average :所有采样器持续时间的总和除以“样本数” Throughput - 每个时间单位的请求数,例如每秒点击次数 中位数和偏差 - 是统计术语 关于您的服务器行为是否可接受 - 这取决于它正在做什么。 601毫秒的平均响应时间对于网上商店来说听起来非常好,但对于财务运营,医疗设备或NASA宇 ...
  • 在这种情况下,通过反射调用方法的性能开销可以忽略不计:我估计反射方法调用大约需要0.1微秒,而客户端和服务器之间的网络延迟很容易达到10毫秒。 也就是说,响应时间的不到0.001%是由于反射开销造成的。 带回家的消息:当被告知事情“慢”时,总是问“与什么相比”,并尝试评估在优化性能之前是否可以产生可测量的性能影响。 (如果您要解决实际性能问题,请测量程序的哪些部分很慢,优化这些部分 - 然后再次测量)。 The performance overhead of invoking the method by r ...
  • Visual Studio Test Explorer窗口与Visual Studio Profiler集成。 您只需在“测试资源管理器”窗口中右键单击“测试”,然后选择“配置文件测试”。 Visual Studio Test Explorer window has integration with Visual Studio Profiler. You just need to right click on the Test in the Test Explorer window and choose P ...