2009-07-22 10 views
5

Il metodo equals() (e anche il metodo compareTo()) può diventare un hotspot di prestazioni (ad esempio in un traffico intenso HashMap). Mi chiedevo quali trucchi hanno adottato le persone per ottimizzare questi metodi per questi casi quando si rivelano necessari.Ottimizzazione metodo equals()

IntelliJ IDEA, ad esempio, genera il seguente:

public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    ... 
} 

Che altro si è imbattuto in che può essere una linea guida per la scrittura di una buona esecuzione equals() metodo?

risposta

14

alcune idee generali che non sono necessariamente specifici per equals()

  • Fail il più presto possibile. Simile allo snippet che hai postato, inizia prima con i criteri di esclusione più ampi e poi diventa più fine, in modo che il metodo possa tornare il più presto possibile
  • Confronta solo gli attributi richiesti per l'uguaglianza. A volte ho visto persone confrontarsi con ogni singola informazione fornita da una classe, anche se solo una manciata di attributi svolge effettivamente un ruolo semantico per l'uguaglianza di due istanze di classe. Questo ovviamente dipende molto dalla classe e dal design
  • Evita la ricorsione dell'uguaglianza, se possibile. A seconda del tipo di attributi di classe si confrontano, si potrebbe ottenere se stessi in situazioni in cui si sta in modo ricorsivo chiamando equals() su se stessi o altri oggetti, che possono avere un impatto sulle prestazioni nascosta

Oltre alle considerazioni sulle prestazioni, don' t dimenticare il equals API contract per garantire che l'uguaglianza è riflessiva, simmetrica, transitiva e coerente e di ignorare sempre hashcode() così, quando si modifica equals().

5

Penso che tu sia già su una parte fondamentale di essa, perché hai detto:

... quando si rivelano necessarie.

Ricordate le regole generali per l'ottimizzazione:

  1. Non
  2. non ... ancora
  3. profilo prima di ottimizzare

li ho sentito in una classe anni fa e il più vicino che posso dire è la fonte C2.

2

Dai un'occhiata a un libro intitolato "Efficace Java" di Joshua Bloch. Ha alcuni suggerimenti sorprendenti e un'intera sezione su questa domanda. In bocca al lupo!

1

È possibile prendere spunto da string interning.

Se gli oggetti sono immutabili, è possibile implementare il proprio "interning" utilizzando un metodo factory statico e inserendo le istanze univoche in una tabella hash. Se lo fai, quando i riferimenti sono uguali gli oggetti sono uguali.

+0

Avrei dovuto menzionare che il metodo factory avrebbe scaricato la stessa istanza dalla tabella hash quando veniva chiamata con valori equivalenti. – devgeezer

+1

Devi stare attento con 'internare'. Può portare a problemi di prestazioni e perdite di archiviazione se fatto in modo errato. In effetti, ecco perché chiamare String.intern() può essere una cattiva idea. –

+0

Queste sono buone precauzioni da tenere a mente. Immagino che il mio consiglio per l'ottimizzazione sarebbe di guardare altrove, a meno che non abbiate prove concrete che Equals (...) sta prendendo un tempo inaccettabilmente lungo. – devgeezer

1

Se gli oggetti si trovano in un ambiente in cui si ha il controllo completo su ciò che chiama equals() su di essi, è necessario tenere traccia del tipo di confronto che si sta eseguendo e regolare il metodo equals() in modo appropriato.

Potreste essere in grado di confermare che alcuni scenari non accadono mai, quindi non c'è bisogno di essere codificato per entro equals(), come ad esempio:

  • confrontando null
  • confronto fra diversi tipi
  • confronto auto

È inoltre possibile decidere un ordine appropriato per i controlli eseguiti, controllando i motivi di errore più comuni st.

5

How to Write an Equality Method in Java è un articolo estremamente dettagliato e ben scritto che spiega le insidie ​​più comuni nello scrivere un metodo di uguaglianza e come evitarli.

0

Suggerisco di rendere HashMap più grande uguale a() è costoso (ad esempio diminuendo il fattore di carico). In questo modo si avranno meno collisioni e si spera che se (o == questo) il rendimento vero corrisponderà più spesso.