-2

Regardless if it is a good or bad OO practice to provide accessors in a class, I'd like to know if executing access to a specific attribute of an object via reflection decrease performance (memory consumption or cpu time).

Have you implemented this and performed a benchmark? Do you know about anyone who has performed such benchmark?

Edit:

Due to some comments which indicates that it's obvious that performance decrease I've modified the title of the question to indicates that I'd like to know how bad is the impact of implementing accessors with reflection.

Edit:

Thank you for your kind comments and answers. Based on the answer from @Peter Lawrey and the kind comment from @EJP, this is what I meant and wanted to know if any of you have implemented prior to my question:

package co.com.prueba.reflection;

import java.lang.reflect.Field;

public class A {

private String s;


public void setS(String s){
    this.s=s;
}

public String getS(){
    return this.s;
}

public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {

    System.out.println("Invoking .setAccesible(true) ...");
    A secondA = new A();
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        Field f = secondA.getClass().getDeclaredField("s");
        f.setAccessible(true);
        f.get(secondA);
        long end = System.nanoTime();
        System.out.println((end - start));
    }

    System.out.println("Without invoking .setAccesible(true) ...");
    A firstA = new A();     
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        Field f = firstA.getClass().getDeclaredField("s");          
        f.get(firstA);
        long end = System.nanoTime();
        System.out.println((end - start));
    }

    System.out.println("Invoking the getter ...");
    A thirdA = new A();
    for(int i=0; i<10; i++){
        long start = System.nanoTime();
        thirdA.getS();
        long end = System.nanoTime();
        System.out.println((end - start));
    }


}

}

Here are the results:

enter image description here

Thank you all.

CoolBeans
  • 20,654
  • 10
  • 86
  • 101
juanpavergara
  • 1,511
  • 1
  • 11
  • 22
  • 3
    Reflection is always slow. – SLaks Jan 04 '13 at 16:32
  • 3
    Of course it's slower and heavyer than just accessing the variable. And it brings many other problems, like the fact you're compilation doesn't verify the coherency of the accesses. – Denys Séguret Jan 04 '13 at 16:32
  • What do you mean exactly, accessors (getters and setters) are not reflection. – Henry Jan 04 '13 at 16:33
  • Please show us some example code, so that we know *exactly* what you mean. – NPE Jan 04 '13 at 16:35
  • 1
    Two basic laws of *using reflection* : 1. The programmer always thinks it's cool. 2. I's almost always a bad idea. – Denys Séguret Jan 04 '13 at 16:35
  • I don't see how this question could be answered in a constructive way. Any benchmark would be specific. – Denys Séguret Jan 04 '13 at 16:39
  • Sorry @dystroy. I don't get your last comment Why does any benchmark would be specific? – juanpavergara Jan 04 '13 at 16:41
  • A benchmark is specific to a specific test. That's why it can't be a definite answer to a (much too) wide question. – Denys Séguret Jan 04 '13 at 16:42
  • @SLaks When warmed up a getter can take about 3 ns via reflection which may not be as slow as your thought. ;) – Peter Lawrey Jan 04 '13 at 16:52
  • I don't see any reason why you couldn't have measured this for yourself on your own target hardware rather than starting an open ended discussion. – user207421 Jan 04 '13 at 18:34
  • If you only take the first <10,000 calls this is before you have warmed up the code (it is not even compiled to native code at this point) I suggest you run the test for at least 2 seconds to ensure it is warmed up enough. – Peter Lawrey Jan 04 '13 at 21:09

4 Answers4

3

On a typical machine the cost of calling a getter via reflection is about 3 ns. A setter is much the same. As a getter can be inlined or even eliminated without reflection there is a high relative difference.

How much difference will 3 ns make to you?

I have supplied a code example and results in my answer HERE yesterday. ;)

Community
  • 1
  • 1
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    @assylias Allot but not to the same extent a direct call will. Before the code has warmed up, the cost is closer to 500 ns if you use setAccessible(true) and 1500 ns if you don't) – Peter Lawrey Jan 04 '13 at 16:49
  • @PeterLawrey this was the base for my implementation. Tks. – juanpavergara Jan 04 '13 at 20:51
2

In order to get just the minimal performance hit that others talk about, be sure to understand that this involves only the reflective call on an already existing Method object. If you do the lookup in every call, the performance hit is huge.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
0

I think this thread answers your question on performance in general. And hope this blog will help you to get some info. on benchmark values. It has some external links such as posts from IBM - Reflection performance benchmark. which discuss about benchmark values.

Community
  • 1
  • 1
0

Java Reflection Performance

It is better than it used to be (I think prior to 1.4) but is still slower than accessing variable directly. I believe it is due to having to load the class and all attributes into memory and then search the list for the one you want.

Accessing a variable directly is recommended (or atleast was) by Google when doing android development to cut out the virtual method call.

Community
  • 1
  • 1
Heath Lilley
  • 393
  • 1
  • 6
  • 11