Reflection-Performance

D

Datenklaun

Gast
Hallo

Bei der Entwicklung von einer Art Interpreter bin ich immer wieder auf die Performance-Schwachstelle von Reflection aufmerksam geworden, weshalb ich mich schon mit Alternativen à la Javassist und so weiter beschäftigt habe, ohne je einen Test gemacht zu haben.
Das wurde heute nachgeholt und führte bei einem Test von Instanzierung und Methodenaufruf zu einem für mich unglaubwürdigen Ergebnis. Daher stellt sich mir die Frage ob in meiner Testmethode ein grober Fehler steckt, den ich übersehe.

Oder kann es sein, daß das Instanzieren von Objekten und das Aufrufen von Methoden per Reflection in Java 7 schon extrem schnell ist? Wenn ja, wie ist es bei älteren JRE's?

In der Methode wird zuerst ein Frame-Object instanziert, die Methoden setTitle, show, und dispose aufgerufen und anschließend das Frame-Object wieder gelöscht. Dieser Ablauf wird durch eine for-Anweisung mehrmals wiederholt, um ein stabileres Ergebnis zu bekommen.
Der selbe Ablauf wird dann mittels Reflection nachgebildet, was jedoch zusätzlich noch das Ermitteln des Class-Objekts und Method-Objekts erfordert.

Umgesetzt habe ich das ganze so:



Java:
public Object[] test()
{

  Object[] ret=new Object[2];
  long time=System.nanoTime();

  for (int i=0;i<44;i++){
    Frame testObj= new Frame();
    testObj.setTitle("Frame 1");
    testObj.show();
    testObj.dispose();
    testObj=null;
  }

  ret[0]=new Long(System.nanoTime()-time);
  time=System.nanoTime();

  for (int i=0;i<44;i++){
    try{
      Class testClass=Class.forName("java.awt.Frame");
      Object testObj=testClass.newInstance();
      testClass.getMethod("setTitle",new Class[]{(new String()).getClass()}).invoke(testObj,new Object[]{new String("Frame 1")});
      testClass.getMethod("show",new Class[]{}).invoke(testObj,new Object[]{});
      testClass.getMethod("dispose",new Class[]{}).invoke(testObj,new Object[]{});
      testClass=null;
      testObj=null;
    }
    catch (Exception e){
    }
  }

  ret[1]=new Long(System.nanoTime()-time);
  return ret;

}


Auf meinem Windos-System ergab die Zeitmessung für die natürliche Instanzierung ca. 4 mia ns und bei der reflektiven 4.5.
Wenn ihr einen markanten Fehler findet, der den Test verfälscht, freue ich mich; wenn der Test stimmt dann kann ich jubilieren und mir (vorerst) den Umweg über Bytecode-Verarbeitung sparen.

Viele Grüße, DerKlaun
 

mvitz

Top Contributor
Leider ein Microbenchmark ohne Aussage:

Java:
public class Test {
    public static void main(String[] args) throws Exception {
        long time = System.nanoTime();
        for (int i = 0; i < 44; i++) {
            javax.swing.JFrame t = new javax.swing.JFrame();
            t.setTitle("Frame 1");
            t.show();
            t.dispose();
            t = null;
        }   
        System.out.println("Instanzierung");
        System.out.println(String.format("%,d ns", System.nanoTime() - time));
        time = System.nanoTime();
        for (int i = 0; i < 44; i++) {
            Class clazz = Class.forName("javax.swing.JFrame");
            Object t = clazz.newInstance();
            clazz.getMethod("setTitle", new Class[]{String.class}).invoke(t, new Object[]{"Frame 1"});
            clazz.getMethod("show",     new Class[]{            }).invoke(t, new Object[]{         }); 
            clazz.getMethod("dispose",  new Class[]{            }).invoke(t, new Object[]{         }); 
            t = null;
            clazz = null;
        }   
        System.out.println("Reflection");
        System.out.println(String.format("%,d ns", System.nanoTime() - time));
    }   
}

führt bei mir zu:
Code:
java -version && javac Test.java && java Test
java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
Note: Test.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Instanzierung
526.264.000 ns
Reflection
384.813.000 ns
-------------------------
java -version && javac Test.java && java Test
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)
Note: Test.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Instanzierung
852.282.569 ns
Reflection
222.950.540 ns
 
S

SlaterB

Gast
du testest intensive Objekte, deren Methoden wie show() solange brauchen, da macht es quasi keinen Unterschied wie sie aufgerufen werden,
wenn man einen Baum auf 30 Meter wachsen läßt und die Zeit misst, ist es relativ egal ob man zu Fuss oder mit dem Auto von der Baumschule nach Hause kam..

generell kann noch gefährlich sein, wenn Dinge anfangs initialisiert werden, ruhig den Test mehrfach laufen lassen in einem Programmablauf

new String().getClass() + new String("Frame 1")
sind unnötig langsam, das lohnt selbst als Test nicht, das kann man in der Realität nicht so buggy coden

-----

hier ein Test mit kleinen Objekten der dann Reflection entsprechend schlecht aussehen lässt:
Java:
public class Test
{
    public static void main(String[] args)
    {
        System.out.println(Arrays.toString(test()));
        System.out.println(count);
    }

    static int count = 0;

    public static Object[] test()
    {
        String x = "hi";
        Object[] ret = new Object[2];
        long time = System.nanoTime();

        int k = 44;
        for (int i = 0; i < k; i++)
        {
            Xy testObj = new Xy();
            testObj.sum(x);
        }

        ret[0] = new Long(System.nanoTime() - time);
        time = System.nanoTime();

        for (int i = 0; i < k; i++)
        {
            try
            {
                Class testClass = Class.forName("test.Test.Xy");
                Object testObj = testClass.newInstance();
                testClass.getMethod("sum", new Class[]
                    {String.class}).invoke(testObj, new Object[]
                    {x});
            }
            catch (Exception e)
            {
            }
        }

        ret[1] = new Long(System.nanoTime() - time);
        return ret;

    }

    public static class Xy
    {

        public static void sum(String x)
        {
            count += x.length();
        }

    }
}
800.000 zu 57 Mio. Nanosekunden, 700x langsamer..

je nachdem ob man lange Methoden aufruft oder kurze wird die konstante Reflection-Arbeit einen hohen oder unbemerkbaren Anteil einnehmen,

bei deinen Frame-Erzeugungen kommen bei mir Zahlen um 200 Mio. heraus, wobei es ohne Reflection nicht unbedingt schneller ist,
das ist nicht gerade logisch, vielleicht finde ich noch was dazu, jedenfalls wären etwa 50 Mio. für Reflection dort schon längst kein Faktor 700 mehr, nur noch 1.25
 
Zuletzt bearbeitet von einem Moderator:
D

datenklaun

Gast
Hallo
Die Bugs sind ja wirklich unangenehm und waren komplett ungeplant. Dazu kann ich nur die Ausrede anführen, noch relativ neu bei Java und in der OOP an sich zu sein.
Danke für die Korrekturen; in Zukunft werde ich es besser machen.
Auch daß das Beispiel mit dem Frame schlecht gewählt ist kann ich nachvollziehen, andererseits finde ich es ganz interessant, daß die Performance-Schwachstelle wohl nicht für alle reflektierten Objekte ein nennenswertes Thema ist.
Danke nochmal für die Auskünfte und viele Grüße, datenklau.
 
D

datenkaun

Gast
Das Programm soll ein Interpreter werden, mit dem Java-Objekte unabhängig vom Compiler benutzt werden können, beispielsweise in einem Applet oder Midlet. Da ich das ganze vielleicht automatisieren möchte, spielt dann die Performance schon eine Rolle, damit ein solches Pseudoprogramm nicht allzusehr humpelt.
 

Wildcard

Top Contributor
Microbenchmarks lassen sich gut mit Japex durchführen. Japex kümmert sich selbstständig um Warm Up Phase und ausreichend Iterationen um ein sinnvolles Ergebnis zu erhalten. Im Beispiel mit dem JFrame bringt auch das allerdings nicht viel, wie SlaterB ja schon erklärt hat. Der zu messende Teil verschwindet im vergleich zum konstanten Aufwand.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
F Performance von Reflection vs Statisches Coden Allgemeine Java-Themen 4
B Reflection gone wrong? Allgemeine Java-Themen 21
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
J Reflection Aufruf: .class durch .dll ersetzen Allgemeine Java-Themen 4
T Reflection - Abprüfen von Klasseneigenschaften Allgemeine Java-Themen 3
perlenfischer1984 Reflection : Element in generische Liste hinzufügen Allgemeine Java-Themen 4
J Reflection-Method Hook? Allgemeine Java-Themen 14
J Reflection mit Klasse und Subklasse Allgemeine Java-Themen 11
X public Getter ersetzen (Reflection?!) Allgemeine Java-Themen 3
A Reflection Problem Allgemeine Java-Themen 15
K Generic class und Reflection Allgemeine Java-Themen 2
G SecurityManager/Policy-File/Reflection Allgemeine Java-Themen 0
N Per Reflection auf (method) local inner class zugreifen? Allgemeine Java-Themen 3
E Reflection? Frage Allgemeine Java-Themen 4
B Reflection, invoke dynamisch befüllen Allgemeine Java-Themen 3
T Reflection Allgemeine Java-Themen 11
G Klassen Cast auf Argumentenklasse via Reflection? Allgemeine Java-Themen 10
H Collections Generics und Reflection Allgemeine Java-Themen 6
TheWhiteShadow Reflection-Lösung für Objektkopien Allgemeine Java-Themen 3
B Reflection: getMethods schlägt fehl (NoClassDefFoundE)) Allgemeine Java-Themen 15
P Reflection "Cast" Allgemeine Java-Themen 5
S Reflection und Generic Allgemeine Java-Themen 9
W Reflection -> getMethod bei optionalen Parametern Allgemeine Java-Themen 4
Kr0e Reflection - Instanz einer Klasse erstellen, ohne Default-Constructor Allgemeine Java-Themen 15
C Probleme mit dem Zugriff auf private Methode per reflection Allgemeine Java-Themen 2
C Zugriff auf private Methode per reflection geht nicht mehr Allgemeine Java-Themen 3
M Probleme mit Reflection Allgemeine Java-Themen 10
A Reflection Konstruktor Parameter Supertyp Allgemeine Java-Themen 2
D Vererbung, Reflection und automatischer Methodenaufruf Allgemeine Java-Themen 24
G Java Reflection Allgemeine Java-Themen 11
N Reflection: NoSuchMethodException obwohl Methode existiert Allgemeine Java-Themen 2
brunothg Problem mit Reflection Allgemeine Java-Themen 6
M reflection in inner classes Allgemeine Java-Themen 7
T Class-files zur Laufzeit zu Reflection-Zwecken laden Allgemeine Java-Themen 18
V Reflection - Field-Instanz und Annotations Allgemeine Java-Themen 6
Y Reflection und "extends" Schlüsselwort Allgemeine Java-Themen 3
R Reflection Problem Allgemeine Java-Themen 4
N getName() of reflection Object Allgemeine Java-Themen 4
P Reflection - Wie rufe ich die Felder einer Klasse in einer Methode der Basisklasse? Allgemeine Java-Themen 4
M Reflection Queue auslesen Allgemeine Java-Themen 6
N generic reflection Allgemeine Java-Themen 5
megachucky Java Reflection -> versteckte Felder finden? Allgemeine Java-Themen 3
MQue Reflection Exception Allgemeine Java-Themen 11
R Problem mit Reflection und Generics Allgemeine Java-Themen 3
ruutaiokwu Per Reflection membervariablen überschreiben / zuweisen / nullen Allgemeine Java-Themen 5
T Zugriff per Reflection o.ä. möglich? Allgemeine Java-Themen 18
R Reflection: Membervariablen-Initialwerte Allgemeine Java-Themen 4
G Reflection Allgemeine Java-Themen 6
V reflection in java 5 und 6 Allgemeine Java-Themen 2
C Reflection Übergabeparamter überprüfen? Allgemeine Java-Themen 3
Ark Konstruktor per Reflection nicht bekannt Allgemeine Java-Themen 4
Q Objekte durch Reflection erzeugen Allgemeine Java-Themen 18
G [Reflection + WebService] Methodenaufruf an einem Proxy Allgemeine Java-Themen 11
T Parameternamen mit Reflection-API Allgemeine Java-Themen 14
M reflection mit parametern Allgemeine Java-Themen 8
M Reflection Frage Allgemeine Java-Themen 7
G Code vereinfachen bei Reflection Allgemeine Java-Themen 4
I reflection get inner static classes Allgemeine Java-Themen 2
C Reflection Allgemeine Java-Themen 12
Y Reflection - wie kann ich eine Methode benutzen Allgemeine Java-Themen 4
Y Reflection - wie anwenden/benutzen bei folgendem Problem Allgemeine Java-Themen 3
P Java Reflection API - ResultDataModel ? Allgemeine Java-Themen 3
R Object Dynamisch erzeugen (Reflection API) Allgemeine Java-Themen 22
N Design-Frage: persistent machen per Reflection Allgemeine Java-Themen 3
G Reflection: aktuelle bzw umschliessende Methode? Allgemeine Java-Themen 7
G per Reflection auf private Klassenattribute zugreifen? Allgemeine Java-Themen 9
G Reflection objekt mit generics erzeugen Allgemeine Java-Themen 5
M per reflection private attributsnamen auslesen Allgemeine Java-Themen 3
G Interface - Klassen implementieren das - Reflection ok? Allgemeine Java-Themen 4
C Reflection Problem! Allgemeine Java-Themen 2
G Object cast via Reflection Allgemeine Java-Themen 8
T Reflection und Typsicherheit Allgemeine Java-Themen 5
Q Umgang mit Reflection Allgemeine Java-Themen 4
S reflection Allgemeine Java-Themen 12
X Reflection performant? Allgemeine Java-Themen 11
M Reflection und Serializable Allgemeine Java-Themen 5
A Reflection - Variablen innerhalb einer Methode ermitteln Allgemeine Java-Themen 9
the[V]oid Primitive Arrays per Reflection erzeugen? Allgemeine Java-Themen 2
W Package via Reflection parsen Allgemeine Java-Themen 4
R Interface mittels Reflection implementieren Allgemeine Java-Themen 8
M reflection Integer != int ? Allgemeine Java-Themen 3
M reflection invoce Allgemeine Java-Themen 3
K Reflection:Zugriff auf innere Klassen Allgemeine Java-Themen 4
N NoSuchMethodException bei Reflection-Versuch, aber warum? Allgemeine Java-Themen 3
byte Methodenaufruf per Reflection? Allgemeine Java-Themen 2
M Generics und Reflection Allgemeine Java-Themen 3
M Array per Reflection manipulieren Allgemeine Java-Themen 5
M Klassen von ausserhalb des Jars per Reflection nachladen Allgemeine Java-Themen 2
thE_29 Reflection Allgemeine Java-Themen 6
M statische Methode per reflection aufrufen Allgemeine Java-Themen 2
B Frage zu Reflection Allgemeine Java-Themen 3
V Reflection - Problem Allgemeine Java-Themen 3
clemson Reflection Interface Allgemeine Java-Themen 4
G mit reflection an die felder einer klasse rankommen Allgemeine Java-Themen 4
N Reflection: An Package einer .class-Datei kommen Allgemeine Java-Themen 2
N Reflection: Feststellen ob eine Klasse abstract ist Allgemeine Java-Themen 3
B Reflection Allgemeine Java-Themen 10
C Reflection und variable casten ! Allgemeine Java-Themen 10
C Reflection - Kurze Beschreibung? Allgemeine Java-Themen 3
F Frage zum Thema Reflection Allgemeine Java-Themen 13

Ähnliche Java Themen

Neue Themen


Oben