2009-03-15 19 views
25

C'è una penalità per chiamare newInstance() o è lo stesso meccanismo sotto? Quante spese generali ci sono di newInstance() sulla nuova parola chiave *?newInstance() vs new

*: scontando il fatto che newInstance() implichi l'uso della riflessione.

risposta

15

In un test del mondo reale, creando 18129 istanze di una classe tramite "Constuctor.newInstance" passando 10 argomenti -vs- creando le istanze tramite "nuovo" il programma non ha avuto alcuna differenza misurabile nel tempo.

Questo non era alcun tipo di micro punto di riferimento.

Questo è con JDK 1.6.0_12 su Windows 7 x86 beta.

Dato che Constructor.newInstance sarà molto simile a Class.forName.newInstance, direi che il sovraccarico non ha quasi nulla a che vedere con la funzionalità che è possibile ottenere utilizzando newInstance su una nuova.

Come sempre, dovresti provarlo tu stesso per vedere.

+1

Controlla http://www.ibm.com/developerworks/java/library/j-jtp02225.html ... questi tipi di benchmark sono molto difficili da ottenere a causa del modo dinamico in cui il codice viene compilato/ottimizzato dal JVM. – Eddie

+0

Come ho detto, è stato un vero esempio mondiale, non un micro benchmark ... – TofuBeer

1

Diffidare dei microbenchmarks, ma ho trovato this blog entry dove qualcuno ha trovato che new era circa due volte più veloce di newInstance con JDK 1.4. Sembra che ci sia una differenza e, come previsto, la riflessione è più lenta. Tuttavia, sembra che la differenza potrebbe non essere un dealbreaker, a seconda della frequenza delle nuove istanze dell'oggetto rispetto a quanto viene eseguito il calcolo.

+0

riflessione ha gooten più veloce con ogni versione di Java. – TofuBeer

+0

Sì, infatti, ecco perché ho menzionato l'uso di 1.4 nel benchmark che ho trovato. Sono sicuro che newInstance sia ancora più lento, ma sarei sorpreso se fosse un'enorme differenza. – Eddie

+0

Chiamare setAccessible (true) sul Constructor dovrebbe renderlo leggermente più veloce (ma assicurarsi che sia ancora sicuro). Naturalmente, suggerirei di evitare riflessioni, se possibile, in ogni caso. –

-1

C'è una differenza - in 10 volte. La differenza assoluta è minuscola, ma se la tua scrittura richiede una bassa latenza, il tempo di CPU cumulativo perso potrebbe essere significativo.

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); 

uscita:

T: 105 
T: 11 

Testato su Xeon W3565 @ 3.2Ghz, Java 1.6

+3

Vorrei dare un'occhiata a questo codice. Durante il runtime, java optimizer interromperà semplicemente l'esecuzione di un nuovo String() perché può dire che così facendo non avranno effetti collaterali. Non farà lo stesso per String.class.newInstance() perché è un riflesso e non è in grado di stabilire se la nuova classe factory Instance ha effetti collaterali. – cmdematos

Problemi correlati