Come evitare "Intuizione di ottimizzazione errata dello sviluppatore"?

22

Ho visto un articolo che ha prodotto questa affermazione:

Developers love to optimize code and with good reason. It is so satisfying and fun. But knowing when to optimize is far more important. Unfortunately, developers generally have horrible intuition about where the performance problems in an application will actually be.

Come può uno sviluppatore evitare questa cattiva intuizione? Ci sono buoni strumenti per trovare quali parti del tuo codice hanno davvero bisogno di ottimizzazione (per Java)? Conosci alcuni articoli, suggerimenti o buone letture su questo argomento?

    
posta Mona 22.08.2011 - 17:47
fonte

10 risposte

44
  • Utilizza un buon profiler per identificare metodi costosi.
  • Documenta quanto tempo gli hot spot hanno effettivamente preso.
  • Scrivi un'implementazione più veloce dei punti caldi
  • Documenta quanto tempo impiegano gli hot spot, si spera che non li facciano più hotspot.

Essenzialmente, devi essere in grado di dimostrare agli altri dove si trovava il problema e che questo cambiamento lo ha fatto sparire.

Non essere in grado di dimostrare un miglioramento, si qualifica - a mio parere personale - per il rollback immediato alla versione originale.

    
risposta data 22.08.2011 - 17:51
fonte
10

L'unico modo per sapere dove ottimizzare è profilare il tuo codice. Invece di apportare modifiche che ritieni possano fornire un vantaggio, sappi con certezza dove si trova il codice con il rendimento peggiore e inizia da lì.

Java lo rende piuttosto facile con lo strumento VisualVM , che è stato associato alle recenti versioni del Java Development Kit (JDK). L'idea è di scoprire quali sono i metodi più utilizzati e in quali metodi stai spendendo la maggior parte del tuo tempo, sia nel codice che nelle librerie esterne. Puoi anche ottenere dati sulle prestazioni sulla garbage collection in modo che tu possa ottimizzare il raccoglitore e regolare lo spazio heap min / max richiesto dall'applicazione.

    
risposta data 22.08.2011 - 17:51
fonte
9

Come chiunque qui sta parlando di profiler mi concentrerò su questa parte della domanda.

How can a developer avoid this bad intuition?

. fare. non. Invece non ottimizzi mai presto .
Ripeti ancora e ancora e ancora, poiché si tratta di un mantra religioso.

Ti troverai a farlo e scoprirai che non dovresti averlo.
E poi di nuovo.
E di nuovo.

Early Optimization è uno dei capitali capitali dei programmatori.

Gli strumenti e le cose fanno parte dell' ottimizzazione successiva che è un'imbarcazione stabilita .

    
risposta data 25.08.2011 - 06:41
fonte
7

Questi strumenti sono chiamati profiler . Puoi usarli per misurare effettivamente quale parte (o parti) del tuo programma impiega più tempo per l'esecuzione, quindi dove concentrare i tuoi sforzi di ottimizzazione.

È altrettanto importante misurare nuovamente dopo le modifiche, per verificare che le modifiche abbiano l'effetto desiderato.

    
risposta data 22.08.2011 - 17:51
fonte
5

Guarda anche quanta memoria utilizza il tuo programma, non solo la sua velocità o il suo tempo di esecuzione.

Un sacco di codificatori che lavorano con linguaggi raccolti come spazzatura come Java hanno l'impressione errata che la raccolta di dati inutili impedisca la perdita di memoria. Questo non è il caso. Se mantieni un riferimento a un oggetto che non ti serve più, non verrà raccolto, e quindi colerà.

Ho visto applicazioni web Java che erano così dispersive da far funzionare il loro server fuori dallo spazio di swap!

Se utilizzi sia un profiler di runtime che un profiler di memoria, imparerai a scrivere codice più veloce e più snello in modo intuitivo. Questo ha l'effetto che il tuo codice ha più probabilità di funzionare velocemente al primo tentativo.

    
risposta data 22.08.2011 - 20:02
fonte
1

il mio rimedio è di iniziare ottenendo risposte chiare a due domande:

  1. come misurare le prestazioni (ad esempio misurare il tempo di caricamento dei dati )
  2. qual è il valore target (ad es. carichi di dati in 3 secondi o meno con una confidenza del 95% )

Approfondito trucco di tiger team ragazzi che sono stati invitati a salvare una versione difettosa del nostro prodotto. Quella release è stata interrotta per motivi di prestazioni, potrebbe rendere l'azienda un cliente strategico che giustificasse il coinvolgimento di tiger (piuttosto costoso). Sono stato incaricato di aiutarli a chiarire i dettagli del progetto; anche usato come un'opportunità per imparare un po 'di più sulle prestazioni.

    
risposta data 24.08.2011 - 11:06
fonte
1

Quello che ho trovato è il miglior antidoto per l'ottimizzazione prematura è questo metodo .

Una volta che lo hai usato per velocizzare il codice (come in questo esempio ), diventa una dipendenza e capisci che il primo principio di ottimizzazione delle prestazioni non è la modifica del codice, è trovare il problema .

L'ottimizzazione reale è l'ottimizzazione prematura poiché la caccia per sfamare la tua famiglia è quella di sparare barattoli di latta. Si tratta di trovare la preda.

    
risposta data 23.08.2011 - 19:10
fonte
1

Vecchia domanda, ma offrirò questa risposta che differisce considerevolmente dalle altre.

Le grandi opportunità per i guadagni in termini di prestazioni derivano dall'elaborazione parallela. Prova a progettare il codice per sfruttare più thread. (Anche se, per semplicità, non lo fai nella versione 1). Piccole congetture o intuizioni necessarie.

Qualsiasi altra cosa è l'ottimizzazione prematura e richiede l'intuizione, che è spesso sbagliata.

    
risposta data 17.12.2017 - 09:22
fonte
0

La tua intuizione può migliorare con il tempo. Lo butterei fuori, forse un po 'controverso, ma in molti anni di utilizzo di VTune e CodeAnalyst e ora di CodeXL, direi che nelle mie intuizioni sono molto più preciso di prima su dove saranno gli hotspot, almeno per il punto in cui non sono più colto di sorpresa quando registro un codice. Ciò non significa che io tenti di ottimizzare le cose alla cieca.

Il profiling ha effettivamente aumentato la mia dipendenza dai profiler, non diminuito. Sto solo dicendo che posso prevedere più facilmente quali saranno i risultati del profiling in una certa misura e inoltre eliminare con successo gli hotspot e migliorare il tempo necessario per completare l'operazione user-end senza prendere pugnalate cieche nel buio e mancanti (qualcosa che tu puoi fare anche quando usi un profiler finché non inizi a capire non solo quali sono gli hotspot, ma perché sono esattamente hotspot rispetto a, ad esempio, errori di cache).

Tuttavia, non è stato fino a quando ho iniziato a utilizzare i profiler che ho iniziato a migliorare quell'intuizione. Uno dei motivi è perché se hai familiarità con il tuo codice, le tue intuizioni potrebbero essere corrette rispetto agli hotspot più grandi e più ovvi, ma non tutte le sottigliezze intermedie. Naturalmente se hai un'operazione di fine utente che richiede un'ora per completare e c'è un algoritmo di complessità quadratica spalancata che elabora un input che copre centomila elementi, puoi probabilmente ottenere ricchi giochi d'azzardo per i tuoi risparmi di tutta la vita sull'idea che sia la complessità quadratica algoritmo in difetto qui. Ma questo non ti dà informazioni dettagliate o, ad esempio, ti consente di sapere esattamente cosa non di contribuire al tempo.

C'è così tanto valore quando si inizia a profilare e vedere dove tutte le cose che pensavate avrebbero potuto essere un grande contributo di tempo non hanno contribuito molto; non le sbalorditive fonti ovvie di inefficienze, ma quelle che sospettate potrebbero essere state leggermente inefficienti ma, dopo averli profilati, rendendosi conto che a malapena hanno contribuito in qualsiasi momento. E questo è potenzialmente il punto in cui ottieni l'intuizione più intuitiva: ti stai sbagliando in tutte quelle aree sottili in cui non è ovvio esattamente quanto tempo è stato speso.

L'intuizione umana oltre l'ovvia complessità algoritmica spesso inizia in modo errato perché ciò che è efficiente per la macchina e ciò che è efficiente per la mente umana sono molto diversi. All'inizio non è così intuitivo pensare alle gerarchie di memoria che vanno dai registri alla cache della CPU alla DRAM sul disco. Non sembra intuitivo pensare che l'aritmetica ridondante possa essere più veloce di fare più ramificazioni o accessi alla memoria di una tabella di ricerca per saltare alcuni lavori di elaborazione. Tendiamo a pensare in termini di quanto lavoro ci sia da fare mentre scartiamo cose come il costo di prendere decisioni e carichi di memoria e negozi. Ciò che è efficiente per l'hardware è spesso molto contro-intuitivo in modi che infrangeranno tutte le tue assunzioni umane a partire, ma naturalmente devi misurare per infrangere le tue ipotesi in modi in cui hai imparato e allineato il tuo intuito più vicino al modo in cui l'hardware funziona davvero.

Il miglioramento dell'intuizione può aiutare, attraverso la creazione di profili, a design dell'interfaccia . I progetti di interfaccia sono molto costosi da cambiare a posteriori, con costi in aumento proporzionali al numero di posti che dipendono da tale interfaccia. Quando inizi a migliorare la tua intuizione, puoi iniziare a progettare le interfacce meglio la prima volta in modi che lasciano spazio per l'ottimizzazione futura senza costosi cambiamenti di progettazione. Di nuovo però, questa intuizione è qualcosa che generalmente sviluppi, e continua a svilupparsi indefinitamente, avendo sempre in mano quel profiler.

    
risposta data 17.12.2017 - 07:49
fonte
0

I profiler aiutano a correggere la cattiva intuizione quando si tratta di codice. Dato quanto oggi l'hardware preveda non è umanamente pratico prevedere le prestazioni del tuo codice, ma era ancora vero anche al tempo di Knuth tanti decenni fa che sostenevano che i profiler dovrebbero essere inclusi come parte degli strumenti standard per lo sviluppo per risolvere il problema. natura "pennywise-and-pound foolish" degli sviluppatori. Ma ho intenzione di seguire una strada molto diversa con questa risposta, data la completezza delle risposte su altri aspetti e dire che la comprensione da parte dell'utente è l'altra "correzione".

Ho assistito, nella mia esperienza personale, a uno sviluppatore particolarmente brillante (ma con gli angoli ciechi su come gli utenti effettivamente utilizzano il software) ottimizzando un algoritmo di suddivisione con profiler in mano (molto buono e costoso e completo: Intel VTune con il campionamento del grafo delle chiamate sopra i profilatori GPU) per le mesh ottenete risultati sorprendenti con miliardi di sfaccettature sulla GPU quando suddividete primitive semplici come cubi con 6 poligoni di gabbia / input. Tranne che ha sintonizzato e messo a punto questo test case che era diverso da qualsiasi caso d'uso del mondo reale (gli utenti non vogliono un miliardo di faccette per un cubo suddiviso che inizia ad assomigliare ad una sfera perfetta, i loro ingressi suddivisione tendono ad essere cose come personaggi e veicoli e altri input complessi). Nel frattempo, quando gli è stato dato un modello di produzione di un'auto con poligoni di input da 120k per suddividere solo un numero relativamente piccolo di sfaccettature, il brillante algoritmo che ha analizzato e profilato ripetutamente ha raggiunto una scansione totale impiegando 15 secondi per inizializzarsi, rendendo la sua soluzione praticamente inutilizzabile per casi d'uso reali.

Stranamente mi sono ulteriormente avvicinato a un cervello quasi funzionale come lui e nessun dottorato di ricerca al mio attivo nella mia carriera per il semplice motivo che ho capito cosa volevano gli utenti, cosa voleva il marketing, cosa volevano i designer. Non posso davvero enfatizzare abbastanza quanto sia utile essere in grado di mettere te stesso nella mentalità e nei panni dell'utente e guardare il tuo software e ciò che deve fare come i tuoi utenti attuali mentre cerchi di separarti dagli sforzi che hai messo nel costruire ciò che hai costruito e guardandolo con un nuovo paio di occhi. Ho persino incontrato dallo sviluppatore sopra che questa è una cosa impossibile da fare; pensava che fossi colpevole di avere un ego simile che tutti gli sviluppatori tecnicamente esperti, ma ignari all'utente, hanno sempre dimostrato di avere torto quando utenti e designer si affollano su di me per parlare esattamente di cosa fare. Sembra molto egocentrico, ma concordo con il disclaimer che non sono un programmatore così geniale, ma capisco cosa vogliono gli utenti e i designer e questo mi ha reso particolarmente favorevole nel mio campo in cui sembrava essere particolarmente raro qualità per qualche ragione. Come programmatori, siamo probabilmente più abituati ad affrontare i test che a capire e socializzare con persone normali e non tecniche.

Quindi c'è la profilazione e la misurazione corretta, ma c'è anche l'esigenza fondamentale di accertarsi che si stia misurando un'operazione con il tipo di input che gli utenti del mondo reale forniranno effettivamente all'applicazione. Altrimenti puoi anche avere VTune o CodeAnalyst o gprof o qualsiasi altro profiler in mano e comunque, mentre cerchi di ottimizzare gli hotspot con quello che potrebbe sembrare un normale test case per lo sviluppatore ma oscuro per gli utenti, finisci per pessimizzare il caso d'uso comune a favore di qualche oscuro caso d'uso che pochi utenti, se ce ne sono, considerano mai l'applicazione.

Alla fine della giornata tutte le difficoltà che tendiamo a portare come sviluppatori possono essere bilanciate con il martello di ferro di ciò che rende gli utenti veramente felici senza risolvere la fame nel mondo, e la necessità pratica di ottenere denaro in modo da poter pagare l'affitto o compra birra o guarda le donne nude o qualunque cosa tu voglia / abbia bisogno di fare. Tutto il resto sta potenzialmente lavorando contro le esigenze aziendali fondamentali, e qualsiasi sviluppatore così nobile, così eroico, così da dimenticare che si tratta di fare soldi e in definitiva soddisfare gli utenti per farli pagare potrebbe fare bene a buttarsi giù per terra e spegni la modalità dio creando mondi virtuali in favore della necessità del mondo reale di spedire semplicemente e ottenere del denaro per il cibo. Possiamo perdere le metriche e le pratiche del software, ma fondamentalmente si tratta davvero di sapere se gli utenti possono pagare i tuoi soldi per sostenere le tue abitudini di consumo.

    
risposta data 04.12.2018 - 17:38
fonte

Leggi altre domande sui tag