zoukankan      html  css  js  c++  java
  • JAVA反射优化

    ****************** 转自 https://my.oschina.net/19921228/blog/3042643 ***********************

    比较反射与正常实例对象的效率

    准备测试对象

    下面先定义一个测试的类TestUser,只有idname属性,以及它们的getter/setter方法,另外还有一个自定义的sayHi方法。

    public class TestUser {
        private Integer id;
        private String name;
        public String sayHi(){
            return "hi";
        }
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }
    测试创建100万个对象
    // 通过普通方式创建TestUser对象
    @Test
    public void testCommon(){
        long start = System.currentTimeMillis();
        TestUser user = null;
        int i = 0;
        while(i<1000000){
            ++i;
            user = new TestUser();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通对象创建耗时:"+(end - start ) + "ms");
    }
    
    //普通对象创建耗时:10ms
    // 通过反射方式创建TestUser对象
    @Test
    public void testReflexNoCache() throws Exception {
        long start = System.currentTimeMillis();
        TestUser user = null;
        int i = 0;
        while(i<1000000){
            ++i;
            user = (TestUser) Class.forName("ReflexDemo.TestUser").newInstance();
        }
        long end = System.currentTimeMillis();
        System.out.println("无缓存反射创建对象耗时:"+(end - start ) + "ms");
    }
    
    //无缓存反射创建对象耗时:926ms

    在上面这两个测试方法中,笔者各自测了5次,把他们消耗的时间取了一个平均值,在输出结果中可以看到一个是10ms,一个是926ms,在创建100W个对象的情况下,反射居然慢了90倍左右。wtf?差距居然这么大?难道反射真的这么慢?下面笔者换一种反射的姿势,继续测试一下,看看结果如何?

    // 通过缓存反射方式创建TestUser对象
    @Test
    public void testReflexWithCache() throws Exception {
        long start = System.currentTimeMillis();
        TestUser user = null;
        Class rUserClass = Class.forName("RefleDemo.TestUser");
        int i = 0;
        while(i<1000000){
            ++i;
            user = (TestUser) rUserClass.newInstance();
        }
        long end = System.currentTimeMillis();
        System.out.println("通过缓存反射创建对象耗时:"+(end - start ) + "ms");
    }
    
    //通过缓存反射创建对象耗时:41ms

    其实通过代码我们可以发现,是Class.forName这个方法比较耗时,它实际上调用了一个本地方法,通过这个方法来要求JVM查找并加载指定的类。所以我们在项目中使用的时候,可以把Class.forName返回的Class对象缓存起来,下一次使用的时候直接从缓存里面获取,这样就极大的提高了获取Class的效率。同理,在我们获取Constructor、Method等对象的时候也可以缓存起来使用,避免每次使用时再来耗费时间创建。

    测试反射调用方法
    @Test
    public void testReflexMethod() throws Exception {
        long start = System.currentTimeMillis();
        Class testUserClass = Class.forName("RefleDemo.TestUser");
        TestUser testUser = (TestUser) testUserClass.newInstance();
        Method method = testUserClass.getMethod("sayHi");
        int i = 0;
        while(i<100000000){
            ++i;
            method.invoke(testUser);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射调用方法耗时:"+(end - start ) + "ms");
    }
    
    //反射调用方法耗时:330ms
    @Test
    public void testReflexMethod() throws Exception {
        long start = System.currentTimeMillis();
        Class testUserClass = Class.forName("RefleDemo.TestUser");
        TestUser testUser = (TestUser) testUserClass.newInstance();
        Method method = testUserClass.getMethod("sayHi");
        int i = 0;
        while(i<100000000){
            ++i;
            method.setAccessible(true);
            method.invoke(testUser);
        }
        long end = System.currentTimeMillis();
        System.out.println("setAccessible=true 反射调用方法耗时:"+(end - start ) + "ms");
    }
    
    //setAccessible=true 反射调用方法耗时:188ms

    这里我们反射调用sayHi方法1亿次,在调用了method.setAccessible(true)后,发现快了将近一半。查看API可以了解到,jdk在设置获取字段,调用方法的时候会执行安全访问检查,而此类操作会比较耗时,所以通过setAccessible(true)的方式可以关闭安全检查,从而提升反射效率。

  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/woniusky/p/10790799.html
Copyright © 2011-2022 走看看