• 反射性能研究,反射赋值与set方法赋值对比


    可能我们有一个模糊的概念,反射性能会慢,但是有多慢没有一个具体的数据。那我就写代码来测试一下。

    package com.itbac.reflection;
    
    import java.lang.reflect.Field;
    
    public class test {
        public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
            long begin = System.currentTimeMillis();
            Book book = new Book();
            book.setName("java从入门到放弃");
            book.setNum(1);
            book.setPrice(1.2);
            System.out.println(book.toString());
                  //循环一千万次
            for (int i = 0; i < 10000000; i++) {
                //1.set方法赋值  耗时毫秒:7
    //            book.setNum(++i);
    
                //2.反射赋值  耗时毫秒:1045
                setFeild(book, i,"num");
            }
            System.out.println(book.toString());
            long end = System.currentTimeMillis();
            System.out.println("毫秒:"+(end-begin));
        }
    
        private static void setFeild(Book book, int i,String str) throws NoSuchFieldException, IllegalAccessException {
            Class<? extends Book> aClass = book.getClass();
            Field num = aClass.getDeclaredField(str);
            num.setAccessible(true);
            num.set(book, i);
        }
    }

    通过上面的测试,我发现在循环赋值一千万次的时候,反射耗时一秒。这个慢才能被人所感知。如果你的反射调用,少于一千万次,请不要说反射慢。

    再看两个方法的对比,set方法直接就能赋值,反射方法还需要获取Class 和 Field ,设置访问权限,好几部操作。我可以用一个map来优化一下。

    package com.itbac.reflection;
    
    import java.lang.reflect.Field;
    import java.util.HashMap;
    import java.util.Map;
    
    public class test {
        public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
            long begin = System.currentTimeMillis();
            Book book = new Book();
            book.setName("java从入门到放弃");
            book.setNum(1);
            book.setPrice(1.2);
            System.out.println(book.toString());
            Map<String, Field> map = new HashMap<>();
                  //循环一千万次
            for (int i = 0; i < 10000000; i++) {
                //1.set方法赋值  耗时毫秒:7
    //            book.setNum(++i);
    
                //2.反射赋值(没有用map)  耗时毫秒:1045
                //3.反射赋值(使用map缓存Field)  耗时毫秒:95
                setFeild(book, i,"num",map);
            }
            System.out.println(book.toString());
            long end = System.currentTimeMillis();
            System.out.println("耗时毫秒:"+(end-begin));
        }
    
        private static void setFeild(Book book, int i,String str,Map<String, Field> map) throws NoSuchFieldException, IllegalAccessException {
            Field field = map.get(str);
            if (null == field) {
                Class<? extends Book> aClass = book.getClass();
                field= aClass.getDeclaredField(str);
                field.setAccessible(true);
                map.put(str, field);
            }
            field.set(book, i);
        }
    }

    这样处理,得出一个数据,95 除以 7  约等于 13.5  ,得出结论,在一千万次调用,反射赋值比直接赋值慢了 13.5倍。

    但是,反射赋值一千万次,才耗时95毫秒,是人无法感知的速度。是可以被我们接受的程序代码运行速度。

    我试着提高反射的次数,看看多少次,才能被我们感觉到慢呢。

    代码运行结果如下:

    一亿次反射赋值,耗时毫秒:687

    两亿次反射赋值,耗时毫秒:1468

    个人的结论:

      反射赋值是比直接赋值慢,但是你在一亿次调用以内,你是感觉不到它慢的,可以放心使用。

    当然,set方法赋值更变态,2亿次赋值,耗时15毫秒。所以能不用反射,就尽量不用反射,实在不行,用也是可以的。

  • 相关阅读:
    为什么写技术博客对新人如此重要?
    Javascript经典正则表达式
    关于读书的那些事,其实我一直...没有行动
    dede织梦CMS文件夹目录结构
    jQ初体验,^_^
    vi/vim 基本使用方法
    (X)HTML Strict 下的嵌套规则
    KISS保持简单:纪念丹尼斯·里奇
    关于jQuery性能优化
    编码规范CSSHTML 摘自kissyui
  • 原文地址:https://www.cnblogs.com/itbac/p/11963086.html
Copyright © 2020-2023  润新知