Come trovare i colli di bottiglia in un'applicazione? [duplicare]

10

Sto costruendo un'applicazione con molti componenti, molti dei quali sono di terze parti, quindi so solo cosa posso ottenere dalla loro documentazione.

Di tanto in tanto, per pura fortuna, ho scoperto che uno di questi componenti era piuttosto pesante e aveva un'opzione per memorizzare dati.

Non posso smettere di pensare che se non fossi fortunato, uno di questi componenti finirebbe per uccidere le prestazioni della mia app e non avrei la minima idea di cosa fare. Finirei per aggiungere più hardware come un idiota.

Quindi come trovi questo tipo di colli di bottiglia? Voglio dire che non avrei una bella relazione che dice "questa parte è lenta", come succede con il database.

Ad esempio, oggi ho scoperto che un serializzatore che stavo usando era pesante e non veniva memorizzato nella cache. Ci sono dei passaggi ripetibili che avrei potuto seguire per scoprire che il serializzatore stava rallentando le cose?

    
posta ChocoDeveloper 21.09.2013 - 00:03
fonte

4 risposte

21

Ci sono due percorsi da seguire.

  1. Segua ciecamente le intuizioni.

  2. Ottieni un profiler dell'applicazione.

Diamo un'occhiata ai pro & cons.

Seguite ciecamente le intuizioni

Questo è:

  • Basso costo di capitale (le intuizioni sono gratuite)
  • Eccezionalmente facile da usare (non c'è nessuna strumentazione)
  • dipende in gran parte dalla tua esperienza di programmazione per vedere i problemi
  • Non estremamente accurato nella ricerca di problemi
  • Ideale per creare buchi di coniglio che consumano quantità incredibili di tempo, ma generalmente non generano miglioramenti molto misurabili. (che presuppone che tu stia misurando le cose)

Profilo dell'applicazione

  • Generalmente ha un costo di acquisizione; e i bravi profiler possono diventare costosi
  • Fornisce misurazioni delle prestazioni dell'applicazione. I migliori isolano i metodi che
    1. Consuma la maggior parte del tempo
    2. Hai il maggior numero di chiamate
  • Richiedi di essere in grado di strumentare la tua applicazione o almeno di passare manualmente attraverso casi d'uso che ti preoccupano.
  • Può sovraccaricarti di troppe informazioni, quindi devi capire cosa cercare

A seconda di quanto è grande la tua applicazione, puoi farcela seguendo le seguenti cieche intuizioni e affidarti al tempo dell'orologio a muro o lanciare alcune chiamate di DateTime nel tuo codice per tenere traccia di quanto dura l'esecuzione. Ho preso personalmente alcune applicazioni con runtime di 24 ore e le ho ridotte a 15 minuti e 1 - 2 ore utilizzando questo approccio. Ma erano piccole applicazioni e potevo capire tutto il codice coinvolto.

D'altra parte, ho usato profiler un paio di volte con applicazioni veramente grandi. Devi essere in grado di ricreare i casi d'uso che sono più preoccupanti e questo può essere un problema. Passare manualmente attraverso lunghi processi può essere problematico. Ma ho usato questi strumenti per tracciare i processi di avvio in background e sono stato in grado di generare miglioramenti significativi delle prestazioni per quelle applicazioni.

Per trovare alcuni profiler, cerca "your_language + profiler" e probabilmente avrai molte opzioni tra cui scegliere.

Segui i commenti:

  1. Mason Wheeler sottolinea correttamente che alcuni buoni profiler possono essere poco costosi. La funzionalità fornita è probabilmente il principale fattore di costo. In un certo senso, è come qualsiasi altro prodotto software: esiste una correlazione tra costi e funzionalità.

  2. Ci può essere un punto a metà strada come indicato da ChocoDeveloper. Puoi creare il tuo profilo personale, ma questo può essere un notevole investimento di tempo. E corri i rischi del sentiero cieco. Se solo sapere il problema è in MyModule.Foo() , allora puoi essere ignaro dei problemi in Module2.Bar() . Ma se sei a conoscenza di quel rischio, puoi assicurarti di profilare tutto.

    • Puoi creare un profiler più leggero in questo modo essendo molto specifico su ciò che viene misurato e registrato. Alcuni dei migliori profiler forniscono anche questa abilità.
  3. I profiler possono essere eseguiti sul codice di produzione. Generalmente non è fatto in quanto hanno un impatto sulle prestazioni (come sottolinea Doc Brown). Ma se non riesci a ricreare i problemi di prestazioni da qualsiasi altra parte tranne la produzione, esegui il profiler in produzione. Devi comprendere i rischi e i potenziali problemi che creerà, ma può essere fatto.

  4. La mia risposta iniziale non ha dato molto credito alla creazione del tuo profilo personale. Nella mia esperienza, ho trovato meno costoso andare con un profiler già esistente che costruire il mio. I profiler non sono necessariamente super, super complicati, ma sono un altro progetto che stai assumendo e dovranno assicurarsi che funzioni correttamente prima di poterti fidare dei risultati. Per le organizzazioni per le quali ho lavorato, la costruzione di un profiler era tangibile alle nostre competenze di base, quindi non era logico per noi farlo.

  5. Dai un'occhiata all'articolo di Wikipedia su Ottimizzazione del programma se non lo hai già fatto. Ecco alcune citazioni scelte citate in quell'articolo.

"Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you have proven that's where the bottleneck is." — Rob Pike

"The First Rule of Program Optimization: Don't do it. The Second Rule of Program Optimization (for experts only!): Don't do it yet." — Michael A. Jackson

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified" — Donald Knuth

    
risposta data 21.09.2013 - 02:29
fonte
8

La risposta di Glen è abbastanza accurata e completa, ma mi piacerebbe lanciare Carica test anche nel mix.

Il profiling è difficile ea volte costoso. È essenzialmente impossibile da fare in produzione. Ma peggio ancora, se l'intero approccio alla gestione delle prestazioni si basa sulla profilazione, non scoprirai questi problemi finché non sarà troppo tardi.

Se la tua squadra / progetto è gestita abbastanza bene, dovresti avere dei test di carico, e questo ovviamente presupponendo che tu abbia già tutti i prerequisiti come l'integrazione continua e i test di integrazione. I buoni test di carico non si limitano a misurare le cose, ma stabiliscono una linea di base, quindi è facile vedere cambiamenti improvvisi o persino graduali.

Quando vedi un'improvvisa variazione nell'output dei tuoi test di carico, sai che è dovuto a una modifica apportata dall'ultima esecuzione di test. E se esegui test di carico ogni giorno o anche ogni settimana, non è affatto difficile tornare ai tuoi passi e scoprire quale commit ha causato il throughput e / o la latenza a fare un tuffo.

Il caricamento dei test potrebbe non aiutarti molto dopo a scoprire un problema nella produzione. Ma una volta raggiunta la performance fino a livelli accettabili, dovresti davvero investire in una soluzione di test di carico in modo da poter ottenere un veloce feedback sui problemi di prestazioni, preferibilmente prima di te 'trincerato in una particolare architettura o prodotto e non può facilmente tornare indietro.

    
risposta data 21.09.2013 - 19:02
fonte
4

Meglio tardi che mai:

So how do you find these kind of bottlenecks? I mean I wouldn't have a nice report saying "this part is slow"...

Ecco come li trovo.

La lentezza non sarà sempre localizzata in nessuna "parte", e se non lo è, ciò non significa che puoi ignorarla.

AGGIUNTO: rispondendo ai commenti, speravo che il video spiegasse meglio, ma @gnat ha un buon punto. Ho scritto molto su questo , e c'è una spiegazione più scientifica qui .

In poche parole, puoi ottenere più campioni di stack in tempo di wall-time, ad esempio da un profiler (se è buono). Il risultato di avere un numero elevato di campioni è che non ti è permesso vedere le informazioni dettagliate in nessuna di esse, ma solo le misurazioni riepilogative, e quelle sono troppo vaghe per dirti cosa potresti correggere.

Ad esempio, può esserci qualcosa distribuito attorno al codice, quindi non è concentrato in alcuna particolare routine, che, se fissa, risparmia il 20% delle volte. Se guardi 10 o 20 campioni, questi verranno visualizzati da 2 a 4 o più, e lo vedrai. Tuttavia, se ci sono 10000 campioni, 2000 o più, farà questa attività, ma dal momento che tutto quello che vedi sono le misurazioni del tempo delle routine, non vedrai il problema.

StackOverflow è pieno di domande sul modulo "che cosa significa questo output di profiler?" Quindi la risposta comune a molti output di profiler è "cos'è questo?" o suo cugino "non c'è modo di accelerare questo codice".

Quando in realtà, c'è un modo, che vedresti se hai esaminato un piccolo numero di campioni in dettaglio.

Questo è il prezzo che paghi per tutti questi campioni.

    
risposta data 25.09.2013 - 16:29
fonte
1

L'ottimizzazione delle prestazioni dovrebbe essere guidata osservando quale risorsa è effettivamente critica per il tempo di esecuzione o per il throughput. In un sistema multiprocesso multiutente, questo è difficile da valutare con un profiler generico e dipende in larga misura dal tipo di applicazione.

I seguenti passaggi dovrebbero essere eseguiti tutte le volte necessarie:

  1. Definisci un obiettivo di rendimento in termini di tempo e / o throughput a cui miri.

  2. Determina la risorsa sovraccaricata (CPU, RAM, Lan, scheda grafica, database separato, processi / handle ...).

  3. Scopri perché si verifica un sovraccarico.

  4. Modifica l'applicazione per ridurre il carico.

  5. Torna a 2. fino a quando il target non viene raggiunto o il tuo budget di tempo è esaurito

Per le applicazioni basate su PC, Microsoft / Sysinterals Process Explorer offre una buona panoramica su quale risorsa potrebbe limitare la prestazione. Utilizza strumenti come top , ntop , iostat o vmstat per ottenere una panoramica sui sistemi Unix . L'eccessivo traffico di file di pagine indica un consumo di memoria troppo elevato. Database come Oracle di solito hanno uno strumento per trovare istruzioni SQL che causano la maggior parte del carico del database.

Assicurarsi che il sistema sottoposto a test sia privo di interferenze esterne (ad esempio scanner di malware). Ripeti i test per rendere i tuoi risultati affidabili.

Dopo aver risolto un collo di bottiglia, potrebbe diventare visibile il collo di bottiglia successivo.

    
risposta data 22.09.2013 - 15:16
fonte

Leggi altre domande sui tag