La profilazione senza benchmark porta a micro-ottimizzazione?

7

Leggi prima: per una definizione dei due termini ("profiling" e "benchmarking") e la necessità di distinguerli, leggi questo answer a un precedente domanda .

Devo ammettere che fino a quando ho visto Winston Ewert 's risposta, non ho mai pensato alla necessità di distinguere le due tecniche. Penso semplicemente che il "profiling" possa essere applicato a diversi "livelli di scala" del software e che quando viene applicato a un livello superiore, il codice di profilazione nei livelli inferiori debba essere disattivato per ridurre il sovraccarico aggregato.

Dopo aver riflettuto sulla risposta, potrebbe aver spiegato perché sono caduto preda della micro-ottimizzazione nel mio precedente progetto.

Nello sforzo di ottimizzare durante quel progetto, ho implementato un profiler low-overhead (inserito nel codice sorgente) che è in grado di generare risultati di profiling accurati al millisecondo. Ho poi passato tutti i giorni ad armeggiare con esso, e ottimizzato un sacco di codice basato sul risultato del profiler. Alla fine, ho avuto successo nel ridurre la parte computazione del progetto da diversi secondi a meno di una frazione di secondo.

La prossima cosa che ho imparato, con mio orrore: quando il modulo ottimizzato era usato in un progetto più ampio, I / O e conversione dei dati dominavano completamente il tempo del calcolo del modulo . La parte di non calcolo è nell'intervallo di 1-2 secondi, rendendo i miei sforzi di ottimizzazione mozzi.

Fino ad oggi, non ho ancora avuto la possibilità di fare un vero "benchmarking", anche se ho intenzione di provarlo molto presto.

Dato che "hai fatto il profiling?" è diventato il cliché su StackOverflow e Programmers.SE, esiste il pericolo che il mio tipo di ignoranza sia effettivamente prevalente tra i colleghi sviluppatori? Questa ignoranza porta a micro-ottimizzazioni ovunque?

    
posta rwong 09.05.2011 - 00:53
fonte

5 risposte

6

Da quello che ho visto il "profilo hai?" la domanda viene sempre dopo "perché funziona così lentamente?" quindi il "benchmarking" è stato fatto e il risultato è stato "troppo lento" e ora stiamo cercando di capire perché funziona così lentamente, quindi andiamo a "definirlo".

La vita reale di solito è più complicata. La velocità del tuo software dipende dalle decisioni di architettura che prendi, dagli algoritmi scelti, dal fatto che tu abbia o meno identificato e gestito correttamente vari colli di bottiglia e vincoli di sistema. Rimanere bloccato ottimizzando un sistema che non è progettato per le prestazioni è una trappola facile a cui cadere e può succhiare enormi quantità di tempo per una piccola ricompensa. D'altra parte, non tutti i software hanno prestazioni elevate come requisito.

Profilazione e ottimizzazione prima del benchmark, ossia prima che tu sappia se le prestazioni sono adeguate o meno, rientra davvero nello scenario di ottimizzazione prematura.

Mi piace questa citazione da Wikipedia :

“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

    
risposta data 09.05.2011 - 01:34
fonte
1

Chi non onora il piccolo non è degno del grande.

Anche se non è possibile rendere la funzione specifica molto più veloce, è possibile che alcuni cicli possano essere sicuri che potrebbero aiutare il sistema nel suo complesso. Prendersi un po 'di tempo libero da molti link in una catena può aggiungere più che semplicemente combattere il link più debole.

Ovviamente devi stare attento a dedicare troppo tempo a questo. Piccole modifiche si impilano però. Piccole modifiche vengono eseguite anche mentre il codice è aggiornato. Normalmente non si presentano in un profiler poiché sono piccoli e sono molti dappertutto.

Prima fallo funzionare, quindi fallo velocemente. A volte è abbastanza veloce, anche se ci sono molte opportunità di miglioramento.

A volte non è "prematuro" se è difficile farlo più tardi.

    
risposta data 09.05.2011 - 01:45
fonte
1

Il profilo deve essere contro scenari realistici (chiama benchmarking se lo desideri). (È un "Dugh"?)

Le soluzioni

O (n²) hanno battuto gravemente O (n log (n)) con un ampio margine dato dataset sufficientemente piccoli. È noto.

I programmi che la maggior parte degli sviluppatori scrive di prima mano non scalano fino a un solo ordine di grandezza sopra. È responsabilità del project manager assicurarsi che tutto sia testato su dataset e scenari di test praticamente in vita e su esecuzioni / secondo per modulo quando necessario.

La gestione del rischio non riguarda l'essere pessimisti. Si tratta di considerare scenari cattivi e fatali nella progettazione e nelle procedure.

    
risposta data 09.05.2011 - 02:39
fonte
1

Given that "Did you do profiling?" has become the cliche on both StackOverflow and Programmers.SE, is there a danger that my kind of ignorance is actually prevalent among fellow developers? Does this ignorance lead to micro-optimizations all over the places?

Penso di sì, dati i tipi di domande e risposte che viaggiano su questi siti e l'esistenza di profilazione dei miti .

È normale sentire le persone inserire il codice di temporizzazione nella loro routine, perché sono infelici o perplessi da ciò che i profiler dicono loro. È anche estremamente comune sentire persone che fanno micro-ottimizzazione indipendentemente dal fatto che abbiano provato o meno la profilazione.

Penso che parte del problema sia la parola "profilazione" stessa. Spesso è confuso con la "misurazione", quando trovare problemi di prestazioni non è affatto lo stesso che misurarli, nella mia esperienza. La misurazione può dire se ciò che hai fatto ha fatto la differenza, ma è una lente d'ingrandimento molto sfocata per trovare cosa risolvere.

C'è una tecnica molto semplice per individuare rapidamente problemi di prestazioni a thread singolo. Una piccola ma crescente frazione di programmatori lo sa. Si basa su un'osservazione molto semplice. Mentre un programma sta facendo qualcosa che in realtà non ha bisogno di fare, puoi vedere di cosa si tratta semplicemente sorprendendolo a caso. Se perdi abbastanza tempo per essere valido, non dovrai sorprenderlo molte volte prima di individuarlo. Quindi puoi vedere, con dettagli precisi, qual è il problema. Ecco di più sul soggetto.

    
risposta data 10.05.2011 - 01:15
fonte
0

In realtà sono della mentalità molto opposta. Il modo più semplice per terminare la micro-tuning di una base di codice inutilmente per ore e molto lontano dalle operazioni di fine utente reali è quello di ossessionare i benchmark.

Si può finire con un rallentamento del test delle prestazioni per impiegare il doppio del tempo e poi sprecare ore con il team che lo ricerca e sintonizzarlo di nuovo quando, nel contesto dell'applicazione, la piccola funzionalità testata richiede solo lo 0,01% di il tempo, cercando di accelerare il backup di un inutile sforzo.

In realtà preferisco mantenere le prestazioni di un codebase piuttosto "organiche", come nel non tentare di consolidare il tutto con infiniti benchmark. Per lo meno, se vuoi aggiungere test delle prestazioni al tuo sistema, assicurati che siano di livello abbastanza alto e abbastanza vicini a quello che gli utenti effettivamente fanno con il software e frequentemente. In realtà non penso che un sistema di compilazione automatizzato non rispetti molto, omettendo i test delle prestazioni a patto che ci siano test di unità / integrazione per la correttezza, e io lavoro in aree critiche per le prestazioni.

La mia ex azienda ha effettuato tutti questi test delle prestazioni per cose finora rimosse dalle operazioni dell'utente, come solo il tempo necessario per chiamare una funzione in un'interfaccia di basso livello un milione di volte e ossessionare alcune fluttuazioni delle prestazioni per quelle aree sono controproducenti rispetto alla profilazione effettiva dell'applicazione rispetto a un caso d'uso del mondo reale. Arrivò persino al punto in cui le persone sprecavano innumerevoli ore di lavoro per indagare sui rallentamenti ai test delle prestazioni a basso livello, mentre le operazioni di alto livello dell'applicazione utente stavano diventando percepibilmente più veloci ... tuttavia gli sviluppatori erano ossessionati dal fatto di recuperare un valore fuori dalla proprietà ha avuto il 30% di tempo in più rispetto a quando sono stati avviati, anche se ciò ha avuto pochissime conseguenze sull'utente. Avrei preferito che fossero loro a profilare l'applicazione rispetto a questi micro-benchmark.

Gli hotspot tendono a spostarsi in casi rari in quanto le cose diventano più efficienti nei percorsi di esecuzione del caso comune, e in quella precedente esperienza, così tanti sviluppatori hanno sprecato tempo ed energie inutili cercando di ottimizzare i casi rari ossessionando questi giovani test sulle prestazioni. Altrettanto importante della misurazione, se non di più, è la completa comprensione di come il software viene comunemente utilizzato. Altrimenti potremmo misurare / benchmarking e mettere a punto le cose sbagliate e, nel peggiore dei casi, rendere effettivamente ciò che gli utenti effettivamente fanno più spesso meno efficiente nel processo.

Per me, la vera cartina di tornasole per capire se stai spendendo il tuo tempo di ottimizzazione in modo produttivo è se stai effettivamente misurando casi d'uso reali che gli utenti del software applicano comunemente e non prendendo pugnalate al buio (almeno misurando ). In genere, i più controproducenti in questo senso sono quelli più separati dal lato utente delle cose, non riuscendo a comprendere l'appeal e gli scenari di utilizzo del caso comune tra gli utenti del software.

Detto questo, penso che la "micro-ottimizzazione" sia più usata oltre la profilazione. Se, per "micro", ciò significa un'ottimizzazione senza alcun impatto sull'utente, anche i miglioramenti algoritmici sostanziali dovrebbero essere considerati "micro", ma non è così che viene tipicamente utilizzato. Spesso "micro" viene usato in modo intercambiabile con "controproducente", quando alcune delle ottimizzazioni più fruttuose e produttive non provengono da scoperte algoritmiche tanto quanto algoritmi pratici che applicano micro-ottimizzazioni efficaci (es: localizzazione migliorata di riferimento). Non mi interessa davvero se è sintonizzazione algoritmica o di basso livello di come i bit e i byte sono disposti in memoria o multithreading o SIMD. Tutto ciò che dovrebbe essere importante è se fa davvero la differenza, e non una funzione minuscola nel sistema chiamato di rado, ma all'utente reale del software.

    
risposta data 03.12.2017 - 20:14
fonte

Leggi altre domande sui tag