Quando l'ottimizzazione non è prematura e quindi non è malvagia?

75

"L'ottimizzazione prematura è la radice di tutti i mali" è qualcosa che quasi tutti noi abbiamo sentito / letto. Quello che mi interessa è il tipo di ottimizzazione non prematura, ovvero in ogni fase dello sviluppo del software (progettazione di alto livello, progettazione dettagliata, implementazione di alto livello, implementazione dettagliata ecc.) Che misura dell'ottimizzazione possiamo considerare senza passare al lato oscuro.

    
posta Gaurav 01.01.2011 - 08:10
fonte

13 risposte

112

Quando si basa sull'esperienza? Non male "Ogni volta che abbiamo fatto X, abbiamo subito un brutale successo nelle prestazioni. Pianifichiamo o ottimizzando o evitando X interamente questa volta."

Quando è relativamente indolore? Non male "Implementare questo come Foo o Bar richiederà altrettanto lavoro, ma in teoria, Bar dovrebbe essere molto più efficiente. Facciamolo al sicuro."

Quando eviti algoritmi di schifo che scaleranno terribilmente? Non male "Il nostro lead tecnologico dice che il nostro algoritmo di selezione dei percorsi proposto viene eseguito in tempi fattoriali, non sono sicuro di cosa significhi, ma suggerisce di commettere seppuku anche solo per considerarlo. Consideriamo qualcos'altro."

Il male deriva dallo spendere un sacco di tempo e problemi di risoluzione di energia che non sai esistere realmente. Quando i problemi esistono definitivamente, o quando il fantasma psico-problema può essere risolto a buon mercato, il male scompare.

Steve314 e Matthieu M. raccoglie punti nei commenti che dovrebbero essere considerati. Fondamentalmente, alcune varietà di ottimizzazioni "indolori" semplicemente non ne valgono la pena, perché il semplice aggiornamento delle prestazioni che offrono non vale la confusione del codice, stanno duplicando i miglioramenti che il compilatore sta già eseguendo, o entrambi. Vedi i commenti per alcuni buoni esempi di non-miglioramenti intelligenti per metà.

    
risposta data 01.01.2011 - 08:45
fonte
35

Il codice dell'applicazione dovrebbe essere buono solo se necessario, ma codice libreria dovrebbe essere il migliore possibile, dal momento che non sai mai come verrà utilizzata la tua libreria. Quindi, quando scrivi il codice della biblioteca, deve essere buono sotto tutti gli aspetti, che si tratti di prestazioni, robustezza o qualsiasi altra categoria.

Inoltre, devi pensare alle prestazioni quando progetta la tua applicazione e quando seleziona algoritmi . Se non è progettato per essere performante, nessun livello di hacker può renderlo performante in seguito e nessuna micro-ottimizzazione supererà un algoritmo superiore.

    
risposta data 01.01.2011 - 21:39
fonte
24

what kind of optimization [is] not premature

Il tipo che viene a seguito di problemi noti.

    
risposta data 01.01.2011 - 08:34
fonte
17

When is optimization not premature and therefore not evil?

È difficile dire ciò che è buono e cattivo. Chi ha questo diritto? Se guardiamo alla natura, sembra che siamo programmati per la sopravvivenza con una definizione ampia di "sopravvivenza" che include il passaggio dei nostri geni alla prole.

Quindi direi, almeno secondo le nostre funzioni e programmazione di base, che l'ottimizzazione non è malvagia quando si allinea con l'obiettivo della riproduzione. Per i ragazzi, ci sono le bionde, le brune, le teste rosse, molte adorabili. Per le ragazze, ci sono ragazzi, e alcuni di loro sembrano andare bene.

Forse dovremmo essere ottimisti verso questo scopo, e lì è utile usare un profiler. Il profiler ti consente di dare la priorità alle ottimizzazioni e al tempo in modo più efficace, oltre a fornirti informazioni dettagliate sugli hotspot e sul motivo per cui si verificano. Ciò ti darà più tempo libero dedicato alla riproduzione e al suo perseguimento.

    
risposta data 03.01.2016 - 20:19
fonte
15

Il preventivo completo definisce quando l'ottimizzazione è non prematuro:

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. [emphasis mine]

È possibile identificare il codice critico in molti modi: strutture o algoritmi di dati critici (ad esempio, utilizzati pesantemente o il "nucleo" del progetto) possono fornire importanti ottimizzazioni, molte ottimizzazioni minori vengono identificate tramite profiler e così via.

    
risposta data 14.01.2011 - 00:56
fonte
11

Dovresti sempre scegliere una soluzione "abbastanza buona" in tutti i casi in base alle tue esperienze.

Il detto di ottimizzazione si riferisce alla scrittura di "codice più complesso di" abbastanza buono "per renderlo più veloce" prima di sapere realmente che è necessario, rendendo quindi il codice più complesso del necessario. La complessità è ciò che rende le cose difficili, quindi non è una buona cosa.

Questo significa che non dovresti scegliere un super complesso "può ordinare file da 100 Gb passandoli in modo trasparente alla routine di ordinamento su disco" quando un ordinamento semplice lo farà, ma dovresti anche fare una buona scelta per l'ordinamento semplice in primo luogo . Scegli ciecamente Bubble Sort o "seleziona tutte le voci casualmente e verifica se sono in ordine." Ripeti. " è raramente buono.

    
risposta data 01.01.2011 - 09:33
fonte
3

La mia regola generale: se non sei sicuro di aver bisogno dell'ottimizzazione, supponi di no. Ma tienilo a mente quando hai bisogno di ottimizzare. Ci sono alcuni problemi che puoi conoscere in anticipo però. Questo di solito comporta la scelta di buoni algoritmi e strutture dati. Ad esempio, se devi verificare l'appartenenza a una raccolta, puoi essere certo che avrai bisogno di un qualche tipo di struttura dati impostata.

    
risposta data 01.01.2011 - 21:52
fonte
3

Nella mia esperienza, nella fase di implementazione dettagliata, la risposta sta nel profilare il codice. È importante sapere cosa deve essere più veloce e cosa è accettabilmente veloce.

È anche importante sapere dove si trova esattamente il collo di bottiglia delle prestazioni: l'ottimizzazione di una parte del codice che richiede solo il 5% del tempo totale di esecuzione non servirà a nulla.

I passaggi 2 e 3 descrivono l'ottimizzazione non prematura:

  1. Falla funzionare
  2. Prova. Non abbastanza veloce? Collegalo .
  3. Utilizzando i dati del passaggio 2, ottimizza le sezioni più lente del codice.
risposta data 07.01.2011 - 00:28
fonte
3

Non è l'ottimizzazione quando si scelgono cose difficili da modificare, ad esempio la piattaforma hardware.

La scelta delle strutture dati è un buon esempio, essenziale per soddisfare i requisiti sia funzionali che non (prestazioni). Non facilmente modificato e tuttavia guiderà tutto il resto nella tua app. Le tue strutture dati cambiano quali algoritmi sono disponibili ecc.

    
risposta data 15.03.2012 - 14:24
fonte
3

Conosco solo un modo per rispondere a questa domanda, e cioè ottenere esperienza nell'ottimizzazione delle prestazioni. Ciò significa: scrivere programmi e dopo che sono scritti, trovare velocità in essi e farlo iterativamente. Ecco un esempio.

Ecco l'errore che la maggior parte delle persone fa: cercano di ottimizzare il programma prima che lo sta effettivamente eseguendo. Se hanno frequentato un corso di programmazione (da un professore che non ha molta esperienza pratica) avranno gli occhiali colorati grandi, e penseranno che questo è tutto su . È lo stesso problema, l'ottimizzazione precedente. **

Qualcuno ha detto: prima fallo bene, quindi fallo velocemente. Avevano ragione.

Ma ora per il kicker: se lo hai fatto un paio di volte, riconosci le cose sciocche che facevi prima, causando problemi di velocità, quindi evitali istintivamente. (Cose come rendere la struttura della tua classe troppo pesante, inondare di notifiche, confondere la dimensione delle chiamate di funzione con il loro costo in termini di tempo, l'elenco potrebbe continuare all'infinito ...) Eviti istintivamente queste cose, ma indovina cosa assomiglia ai meno esperti: ottimizzazione prematura!

Quindi questi stupidi dibattiti vanno avanti e avanti:)

** Un'altra cosa che dicono è che non devi più preoccupartene, perché i compilatori sono così bravi e le macchine sono così veloci al giorno d'oggi. (KIWI - Kill It With Iron.) Non ci sono aumenti esponenziali dell'hardware o del sistema (fatti da ingegneri molto intelligenti che lavorano duramente) che possono eventualmente compensare i rallentamenti esponenziali del software (fatti da programmatori che la pensano così).

    
risposta data 30.09.2015 - 15:46
fonte
2

Quando i requisiti o il mercato lo richiedono espressamente.

Ad esempio, le prestazioni sono un requisito nella maggior parte delle applicazioni finanziarie perché la bassa latenza è fondamentale. A seconda della natura dello strumento negoziato, l'ottimizzazione può passare dall'utilizzo di algoritmi non bloccanti in un linguaggio di alto livello all'utilizzo di un linguaggio di basso livello e persino l'estremo - implementando gli algoritmi di corrispondenza degli ordini nell'hardware stesso (utilizzando FPGA ad esempio ).

Altri esempi potrebbero essere alcuni tipi di dispositivi incorporati. Prendiamo ad esempio il freno ABS; in primo luogo c'è la sicurezza, quando si colpisce la pausa l'auto dovrebbe rallentare. Ma ci sono anche prestazioni, non vorrai ritardi quando fai una pausa.

    
risposta data 16.06.2015 - 09:24
fonte
0

La maggior parte delle persone definirebbe l'ottimizzazione prematura, se si sta ottimizzando qualcosa che non si traduce in un "soft failure" (funziona ma è comunque inutile) del sistema a causa delle prestazioni.

Esempi di mondo reale.

  • Se il mio ordinamento di bolle richiede 20 ms per l'esecuzione, ottimizzandolo su quicksort 1ms non migliorerà l'utilità generale in alcun modo significativo nonostante un aumento delle prestazioni del 2000%.

  • Se una pagina web richiede 20 secondi per caricarla e la riduciamo a 1 secondo, questo può aumentare l'utilità del sito da 0 a quasi infinito. Fondamentalmente qualcosa che è stato rotto perché era troppo lento, è ora utile.

risposta data 15.06.2015 - 21:59
fonte
0

Che tipo di ottimizzazione non è prematura?

Un'ottimizzazione che corregge un problema di prestazioni noto con l'applicazione o un'ottimizzazione che consente all'applicazione di soddisfare criteri di accettazione ben definiti.

Dopo essere stati identificati, dovrebbe essere necessario un po 'di tempo per stabilire la correzione e misurare il beneficio in termini di prestazioni.

(cioè non è - "Penso che questo bit del codice sembra che potrebbe essere lento, cambierò X per usare Y invece e sarà più veloce").

Ho riscontrato molta "ottimizzazione" prematura che ha reso il codice più lento - in questo caso, mi sembra prematuro voler dire "non pensato". Le prestazioni dovrebbero essere confrontate prima e dopo l'ottimizzazione e solo il codice che migliora effettivamente le prestazioni.

    
risposta data 20.12.2017 - 17:44
fonte

Leggi altre domande sui tag