2012-11-08 4 views
12

Ho una classe di utilità che ha metodi non statici senza variabili di istanza. Quindi sto pensando di convertire tutti i metodi in metodi static. Dubito che ci saranno impatti sulla memoria o sulle prestazioni. Ma volevo solo confermare.prestazioni del metodo statico o non statico per una classe di utilità

La modifica di un metodo come static avrà un impatto sulle prestazioni sul programma?

risposta

17

Un'ultima cosa da aggiungere a ciò che le persone hanno detto qui.

L'utilizzo di un metodo static presenta un sovraccarico leggermente inferiore dovuto al fatto che è stato garantito il binding in fase di compilazione. Le chiamate al metodo statico creeranno l'istruzione bytecode invokestatic. ]

In uno scenario tipico, i metodi di istanza sono associati al runtime e creeranno l'istruzione bytecode invokevirtual che ha un sovraccarico superiore a invokestatic.

Tuttavia, questo diventa rilevante solo nel caso di milioni di iterazioni probabili, e vorrei mettere in guardia contro questo aspetto del design della vostra classe. Fai ciò che ha senso dal punto di vista del design. In base alla tua descrizione, i metodi static sono probabilmente la scelta giusta. In effetti, questa è una pratica relativamente normale per creare una classe di utilità:

public class MyUtilities { 
    private MyUtilities() { } // don't let anyone construct it. 
    public static String foo(String s) { ... } 
} 
+1

La storia è un po 'più complicata dal momento che 'invokevirtual' non è un'istruzione di macchina reale. Nel peggiore dei casi verrà implementato come sito di chiamata monomorfico, ma se la classe è definitiva (o effettivamente definitiva in virtù del costruttore privato), sarà una chiamata cablata. Anche senza questo, il runtime potrebbe notare che non ci sono sottoclassi e la chiamata è comunque cablata. –

+0

Sì, capisco che non garantisce che non è cablato, ma stavo cercando di mantenere la spiegazione semplice, in quanto la maggior parte delle persone non capisce gli interni del jvm. – Matt

+1

Devo dire che la tua formulazione è fuorviante. Non esiste uno "scenario tipico" qui: invocazione del metodo di istanza ** sempre ** compila a 'invokevirtual'; allo stesso modo con metodo statico e 'invokestatic'. –

1

È comune per le classi di utilità senza stato (ad esempio java.lang.Math ad esempio) avere metodi statici pubblici. In questo modo non è necessario creare un'istanza della classe per usarla.

3

Se la classe di utilità non è sottoclasse, la conversione di metodi che non accedono alle variabili di istanza su static è una buona idea. Si dovrebbe passare attraverso il codice e convertire invocazioni alla sintassi statica, cioè

int res = utilityInstance.someMethod(arg1, arg2); 

devono essere convertiti in

int res = UtilityClass.someMethod(arg1, arg2); 

per chiarezza.

Non ci saranno impatti evidenti sulle prestazioni: sebbene le invocazioni teoriche siano leggermente meno costose, la differenza è troppo piccola per essere considerata importante nella maggior parte degli scenari.

-1

La differenza è che avete bisogno di un'istanza al fine di utilizzare, in modo che l'utente deve fare un'istanza che sarà un

3

Ci sono due requisiti che devono essere soddisfatti per un metodo per essere ammissibili per la conversione in static:

  1. nessuna variabile di istanza a cui si accede (questo è soddisfatto nel tuo caso);
  2. non avrà mai bisogno di essere sottoposto a override (per questo potrebbe essere necessario pensare attraverso).

Tuttavia, quando questi requisiti sono soddisfatti, in realtà è consigliato per rendere il metodo statico perché restringe contesto il metodo viene eseguito all'interno.

Infine, ci sono senza problemi di prestazioni per parlare di qui e qualsiasi differenza teorica è in realtà a favore di metodi statici poiché non implicano la risoluzione del metodo dinamico. Tuttavia, l'invocazione del metodo di istanza è estremamente rapida in qualsiasi implementazione JVM pertinente.

Per quanto riguarda la memoria, la storia è la stessa: una differenza teorica è a favore del metodo statico, ma non vi è alcuna differenza pratica se confrontata con una classe di utilità singleton.

17

MODIFICA: Affrontare l'aspetto delle prestazioni: è più economico non dover creare un'istanza di qualcosa inutilmente, ma la differenza è molto probabile che sia completamente irrilevante. Concentrarsi su un design chiaro è molto più probabile che sia importante nel tempo.

metodi di utilità sono spesso statica, e se tutti i metodi di una classe sono statici può ben essere la pena di fare la classe final e comprendente un costruttore privato a prevenire instantation.Fondamentalmente, con classi di utilità che non rappresentano alcuna "cosa" reale, non ha senso logico costruire un'istanza, quindi prevenirla.

D'altra parte, questo non ridurre la flessibilità: se uno qualsiasi di questi metodi di utilità contengono funzionalità che si può decidere di variare polimorfico (ad esempio a scopo di test) quindi prendere in considerazione lasciandoli come metodi di istanza - e cercare di estrarre qualche classe significativa nome per rappresentare la "cosa" coinvolta. (Ad esempio, unha un istanziale - a no.)

+4

+1 per il secondo paragrafo. Se vengono utilizzati metodi statici, non sarebbe possibile scambiare l'implementazione. –

+0

@MarkoTopolnik: ho aggiunto una sezione all'inizio della risposta. –

0

Metodo statico buona idea quando si intende utilizzare la funzionalità particolare molto spesso.