Java Language Un approccio evidence-based all'ottimizzazione delle prestazioni di Java


Esempio

Donald Knuth è spesso citato come dicendo questo:

"I programmatori sprecano enormi quantità di tempo a pensare, o preoccuparsi, la velocità di parti non critiche dei loro programmi, e questi tentativi di efficienza in realtà avere un forte impatto negativo quando il debug e la manutenzione sono considerati. Dobbiamo dimenticare le piccole efficienze, dicono di Il 97% delle volte : l'ottimizzazione prematura è la radice di tutti i mali, tuttavia non dovremmo perdere le nostre opportunità in quel 3% critico ".

fonte

Tenendo presente questo consiglio, ecco la procedura consigliata per l'ottimizzazione dei programmi:

  1. Prima di tutto, progetta e codifica il tuo programma o libreria con particolare attenzione alla semplicità e alla correttezza. Per cominciare, non spendere molto per le prestazioni.

  2. Portalo a uno stato di lavoro e (idealmente) sviluppa test unitari per le parti chiave del codice base.

  3. Sviluppare un benchmark delle prestazioni a livello di applicazione. Il benchmark dovrebbe coprire gli aspetti critici delle prestazioni della vostra applicazione e dovrebbe eseguire una serie di attività tipiche di come l'applicazione verrà utilizzata nella produzione.

  4. Misura le prestazioni.

  5. Confronta le prestazioni misurate con i tuoi criteri per la velocità con cui l'applicazione deve essere. (Evita criteri non realistici, irraggiungibili o non quantificabili come "il più velocemente possibile".)

  6. Se hai soddisfatto i criteri, FERMA. Il lavoro è finito (Qualsiasi ulteriore sforzo è probabilmente una perdita di tempo.)

  7. Profili l'applicazione mentre sta eseguendo il tuo benchmark delle prestazioni.

  8. Esamina i risultati del profilo e scegli i "hotspot di prestazione" più grandi (non ottimizzati); cioè sezioni del codice in cui l'applicazione sembra passare più tempo.

  9. Analizza la sezione del codice hotspot per cercare di capire perché è un collo di bottiglia e pensa a un modo per renderlo più veloce.

  10. Implementalo come una proposta di modifica del codice, test e debug.

  11. Rieseguire il benchmark per vedere se il cambio di codice ha migliorato le prestazioni:

    • Se Sì, quindi tornare al passaggio 4.
    • Se No, abbandonare la modifica e tornare al punto 9. Se non si stanno facendo progressi, selezionare un punto di attivazione diverso per l'attenzione.

Alla fine arriverete a un punto in cui l'applicazione è abbastanza veloce o avete preso in considerazione tutti gli hotspot significativi. A questo punto devi fermare questo approccio. Se una sezione di codice sta consumando (diciamo) l'1% del tempo complessivo, allora anche un miglioramento del 50% renderà l'applicazione solo dello 0,5% più veloce nel complesso.

Chiaramente, c'è un punto oltre il quale l'ottimizzazione dell'hotspot è uno spreco di energie. Se arrivi a quel punto, devi adottare un approccio più radicale. Per esempio:

  • Guarda la complessità algoritmica dei tuoi algoritmi core.
  • Se l'applicazione sta spendendo un sacco di tempo per la garbage collection, cerca modi per ridurre la velocità di creazione dell'oggetto.
  • Se le parti chiave dell'applicazione sono ad uso intensivo della CPU e single-thread, cerca opportunità per il parallelismo.
  • Se l'applicazione è già multi-thread, cerca i colli di bottiglia della concorrenza.

Ma ovunque sia possibile, affidati a strumenti e misure piuttosto che all'istinto per indirizzare i tuoi sforzi di ottimizzazione.