mardi 6 avril 2021

Java reflection vs non reflection performance comparison [duplicate]

So I tried to test the performance of java reflection. I want to add every value of every field in a class into a map.

 public static class testClass {
    String monday = "Monday";
    String tuesday = "Tuesday";
    String wednesday = "Wednesday";
    String thursday = "Thursday";
    String friday = "Friday";
    String saturday = "Saturday";
    String sunday = "Sunday";
    ... getter and setters ...
}


public static void main(String args[]) {
    noReflection();
    reflection();
}

public static void noReflection() {
    testClass test = new testClass();
    long start = System.nanoTime();
    Map myMap = new HashMap<>();
    for (int i = 0; i < RUNS; i++) {
        List<Integer> myList = new ArrayList<>();
        for(myDayz days: myDayz.values()) {
            myList.add(days.ordinal());
        }
        myMap.put(myList.get(0),test.getMonday());
        myMap.put(myList.get(1),test.getFriday());
        myMap.put(myList.get(2),test.getSaturday());
        myMap.put(myList.get(3),test.getSunday());
        myMap.put(myList.get(4),test.getThursday());
        myMap.put(myList.get(5),test.getTuesday());
        myMap.put(myList.get(6),test.getWednesday());

        myMap.clear();
    }
    System.out.printf("no reflection: %,d ns%n", (System.nanoTime() - start)/RUNS);
}

public static void reflection() {
    testClass as = new testClass();
    long start = System.nanoTime();
    final String stringClassName = String.class.getName();

    Map myMap = new HashMap<>();
    for (int i = 0; i < RUNS; i++) {
        int enumIndex = 0;
        List<Integer> myList = getEnumsAsList(myDayz.class);
        for(Field field : as.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            String fieldTypeName = field.getGenericType().getTypeName();
            try {
                Object instance = field.get(as);
                if (instance != null && fieldTypeName.equals(stringClassName)) {
                    myMap.put(myList.get(enumIndex),(String) instance);
                    enumIndex++;
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        myMap.clear();
    }
    System.out.printf("reflection: %,d ns%n", (System.nanoTime() - start)/RUNS);
}

private static <E extends Enum<E>> List<Integer> getEnumsAsList(Class<E> eClass) {
    List<Integer> enumOrdinals = new ArrayList<>();
    for (E en : EnumSet.allOf(eClass))
    {
        enumOrdinals.add(en.ordinal());
    }
    return enumOrdinals;
}

private enum myDayz {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

Now what suprised me is that the non reflection code is about ~60% faster. I thought it would be ALOT faster. My question is if this is what you can expect or have i done something wrong here?





Aucun commentaire:

Enregistrer un commentaire