Ho visto altri thread che dicono che le prestazioni di java reflection sono 10-100x più lente rispetto a quando si usano le chiamate senza riflessione.Interpretazione delle prestazioni della riflessione Java: perché è sorprendentemente molto veloce?
I miei test in 1.6 hanno dimostrato che questo non è il caso, ma ho trovato alcune altre cose interessanti che ho bisogno di qualcuno che mi spieghi.
Ho oggetti che implementano la mia interfaccia. Ho fatto tre cose 1) usando un riferimento ad un oggetto I che ho lanciato quell'oggetto all'interfaccia e chiamo il metodo attraverso l'interfaccia 2) usando un riferimento all'oggetto reale, chiamiamo direttamente il metodo e 3) chiamiamo il metodo attraverso il riflesso. Ho visto che la prima chiamata all'interfaccia è stata la più veloce seguita da vicino dal riflesso n. 3, ma ho notato che la chiamata diretta al metodo era la più lenta con un buon margine.
Non lo capisco, mi sarei aspettato che la chiamata diretta fosse più veloce, quindi l'interfaccia, quindi la riflessione sarebbe stata molto più lenta.
Blah e ComplexClass si trovano in un pacchetto diverso dalla classe principale ed entrambi hanno un metodo doSomething (int x) che implementa l'interfaccia e stampa solo il numero intero x.
Qui ci sono i miei risultati (tempi in ms, risultati molto simili w prove multiple /): chiamando un metodo direttamente: 107.194 chiamare un metodo direttamente da un cast oggetto a un'interfaccia: 89594 chiamando un metodo attraverso la riflessione: 90453
Ecco il mio codice:
public class Main
{
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
Blah x = new Blah();
ComplexClass cc = new ComplexClass();
test((Object) x, cc);
}
public static void test(Object x, ComplexClass cc)
{
long start, end;
long time1, time2, time3 = 0;
int numToDo = 1000000;
MyInterface interfaceClass = (MyInterface) x;
//warming up the cache
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
cc.doSomething(i); //calls a method directly
}
end = System.currentTimeMillis();
time1 = end - start;
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
interfaceClass.doSomething(i); //casts an object to an interface then calls the method
}
end = System.currentTimeMillis();
time2 = end - start;
try
{
Class xClass = x.getClass();
Class[] argTypes =
{
int.class
};
Method m = xClass.getMethod("doSomething", argTypes);
Object[] paramList = new Object[1];
start = System.currentTimeMillis();
for (int i = 0; i < numToDo; i++)
{
paramList[0] = i;
m.invoke(x, paramList); //calls via reflection
}
end = System.currentTimeMillis();
time3 = end - start;
} catch (Exception ex)
{
}
System.out.println("calling a method directly: " + time1);
System.out.println("calling a method directly from an object cast to an interface: " + time2);
System.out.println("calling a method through reflection: " + time3);
}
WHY CW? è una domanda relativa alla programmazione non soggettiva valida? E perché i voti per chiudere ?! – hhafez
Ho trasformato il titolo in una domanda per coloro che non possono vedere una domanda a meno che non abbia il marchio. Ma, wiki della comunità ?? –