2009-03-15 3 views
25

Gibt es eine Strafe für den Aufruf von newInstance() oder ist es der gleiche Mechanismus darunter? Wie viel Overhead hat newInstance() bei einem neuen Keyword *?newInstance() vs neu

*: Abgesehen davon, dass newInstance() die Verwendung von Reflektion impliziert.

Antwort

15

In einem realen Test, 18129 Instanzen einer Klasse über "Constructor.newInstance" erstellen und 10 Argumente -vs- übergeben, die die Instanzen über "neu" erstellen, hat das Programm keinen messbaren Zeitunterschied gemacht.

Dies war keine Art von Mikro-Benchmark.

Dies ist mit JDK 1.6.0_12 auf Windows 7 x86 Beta.

Vorausgesetzt, dass Constructor.newInstance wird sehr ähnlich zu Class.forName.newInstance würde ich sagen, dass der Overhead ist kaum etwas gegeben die Funktionalität, die Sie mit NewInstance über neue erhalten können.

Wie immer sollten Sie es selbst testen, um zu sehen.

+1

Schauen Sie sich http://www.ibm.com/developerworks/java/library/j-jtp02225.html an ... diese Art von Benchmarks sind aufgrund der dynamischen Art und Weise, wie Code von der JVM. – Eddie

+0

Wie ich schon sagte, es war ein Beispiel aus der realen Welt, kein Mikro-Benchmark ... – TofuBeer

1

Seien Sie vorsichtig Microbenchmarks, aber ich fand this blog entry wo jemand gefunden, dass new war etwa doppelt so schnell wie newInstance mit JDK 1.4. Es klingt, als gäbe es einen Unterschied, und wie erwartet ist die Reflexion langsamer. Es klingt jedoch so, als ob der Unterschied kein Dealbreaker ist, abhängig von der Häufigkeit neuer Objektinstanzen im Vergleich zu der Anzahl der durchgeführten Berechnungen.

+0

Reflexion ist mit jeder Version von Java gooten schneller. – TofuBeer

+0

Ja, tatsächlich, weshalb ich die Verwendung von 1.4 in dem Benchmark, den ich gefunden habe, erwähnt habe. Ich bin mir sicher, dass newInstance noch langsamer ist, aber ich wäre überrascht, wenn es ein großer Unterschied wäre. – Eddie

+0

Aufruf von SetAccessible (True) auf dem Konstruktor sollte es etwas schneller machen (aber stellen Sie sicher, noch sicher). Natürlich würde ich vorschlagen, Reflexion möglichst zu vermeiden. –

-1

Es gibt einen Unterschied - in 10-mal. Der absolute Unterschied ist winzig, aber wenn Sie die kumulative CPU-Zeit Ihrer Anwendung mit geringer Latenzzeit schreiben, ist dies möglicherweise von Bedeutung.

long start, end; 
    int X = 10000000; 
    ArrayList l = new ArrayList(X); 
    start = System.nanoTime(); 
    for(int i = 0; i < X; i++){ 
     String.class.newInstance(); 
    } 
    end = System.nanoTime(); 
    log("T: ", (end - start)/X); 

    l.clear(); 
    start = System.nanoTime(); 
    for(int i = 0; i < X; i++){ 
     new String(); 
    } 
    end = System.nanoTime(); 
    log("T: ", (end - start)/X); 

Ausgang:

T: 105 
T: 11 

auf Xeon W3565 @ 3.2Ghz getestet, Java 1.6

+3

Ich würde mir diesen Code genau ansehen. Während der Laufzeit wird der Java-Optimierer einfach die Ausführung von String() stoppen, da er feststellen kann, dass dies keine Nebenwirkungen hat. Bei String.class.newInstance() wird das nicht der Fall sein, da es sich um eine Reflektion handelt, und es kann nicht erkennen, ob die Klassenklasse newInstance Nebenwirkungen hat. – cmdematos