Domanda

C'è qualche differenza in termini di efficienza (ad esempio tempi di esecuzione, la dimensione del codice, ecc) tra questi due modi di fare le cose?

Esempi Di seguito sono ideati che creano oggetti e non fare nulla, ma i miei scenari effettivi possono essere la creazione di nuove discussioni, ascoltatori, ecc Si assumano i seguenti pezzi di codice avvengono in un ciclo in modo che possa fare la differenza.

Utilizzando oggetti anonimi:

void doSomething() {
    for (/* Assume some loop */) {
        final Object obj1, obj2; // some free variables

        IWorker anonymousWorker = new IWorker() {
            doWork() {
                // do things that refer to obj1 and obj2
            }
        };
    }
}

La definizione di una prima classe:

void doSomething() {
    for (/* Assume some loop */) {
        Object obj1, obj2;
        IWorker worker = new Worker(obj1, obj2);
    }
}

static class Worker implements IWorker {
    private Object obj1, obj2;
    public CustomObject(Object obj1, Object obj2) {/* blah blah */}

    @Override
    public void doWork() {}
};
È stato utile?

Soluzione

solo differenza pratica tra le classi anonime e le classi di livello superiore è che le classi anonime terranno un implicito riferimento alla classe esterna.

Non si manifesterà in termini di prestazioni, ma avrà un impatto voi se mai serialise queste classi.

Altri suggerimenti

Non ci dovrebbe essere poca o nessuna differenza di prestazioni. Se c'è una differenza sarà a un livello in cui non è un valore di circa preoccupante.

IMO, si dovrebbe concentrarsi sulla scrittura del codice che è leggibile e mantenibile, e ignorare i problemi di prestazioni "micro" fino ad avere trasparente la prova che essi sono significativi ... sulla base di profiling l'applicazione.

(Per inciso, quando una classe interna anonima riferisce ad un final in un ambito di inclusione, questa viene implementata a livello di bytecode mediante argomenti del costruttore nascosti e attributi di istanza nascosti. I codici di byte sarà quasi lo stesso del bytecode che si ottiene dalla vostra altra implementazione.)

E 'importante rendersi conto che le classi anonime sono ancora le classi che erano noti e completamente compilati al momento della compilazione. Il fatto che, ad esempio, si sta definendo un organo classe anonima, magari con molti metodi e campi ecc all'interno di un ciclo, non significa che il runtime deve di compilazione che tipo su ogni iterazione.

Pertanto, qualsiasi differenza di prestazioni tra i due approcci sono trascurabili. I fattori importanti da considerare sono cose come la leggibilità, la riusabilità, verificabilità, ecc.

Io in realtà ho notato un calo di prestazioni significato se un'istanza molti casi di una classe anonima.

Pensare se potrebbe essere dovuto alla classe di essere statica locale che ho rimosso e non faceva alcuna differenza.

Nel mio caso, stavo facendo qualcosa di 1.000 scegliere 3 volte che è 499.500. La versione con la classe locale (a prescindere dalla statico o no) ha preso 26 secondi e la versione con l'anonimo classe funzionalmente identici sono voluti 2 minuti e 20 secondi.

Per quanto riguarda le prestazioni si dovrebbe prendere in considerazione se una classe interna deve essere creato o non a tutti.

Un esempio di cattiva pratica è qualcosa di simile:

public List<String> someMethod() {
       return new ArrayList<String>() {{
                      add("Item one");
                      add("Item two");
              }};
}

Mentre questa convenienza sintattica sembra intelligente a un primo sguardo, questo (spesso inosservata) crea una classe interna anonima che ha per oggetto mantiene un riferimento all'istanza esterna. Dato che questo oggetto è dato anche verso l'esterno, come valore del risultato di someMethod, non si può essere sicuri di cosa il vostro interlocutore fa con questa lista. Se si mette l'istanza ArrayList risultante in qualche variabile statica, il vostro oggetto corrente verrà mantenuta per sempre troppo!

Speculare sulle prestazioni del codice è un ottimo modo di sprecare il vostro tempo. Nulla è paragonabile alla realtà di benchmarking il codice. Se siete preoccupati per le prestazioni, misurare il codice . Se si sospetta che il codice è sub-ottimale, profilo il codice per capire dove il tempo è trascorso, quindi provare a migliorare quelle parti. A questo punto può essere opportuno per studiare in realtà il codice di byte per vedere se questo può darvi un suggerimento, che è più efficiente implementazione.

Quando hai fatto che, misurare nuovamente il codice per fare in modo che non hai fatto le cose peggiori, ad esempio rendendo il codice più brutto e più difficile da mantenere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top