反射性能研究,反射賦值與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毫秒。所以能不用反射,就盡量不用反射,實在不行,用也是可以的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM