Come affrontare i malintesi su "l'ottimizzazione prematura è la radice di tutti i mali"?

26

Ho incontrato molte persone che sono dogmaticamente contro tutto ciò che può essere considerato "ottimizzazione" nel senso generale della lingua inglese della parola, e molto spesso citano alla lettera la citazione (parziale) "l'ottimizzazione prematura è la radice di tutto il male "come giustificazione per la loro posizione, sottintendendo che interpretano qualunque cosa di cui sto parlando sia" ottimizzazione prematura ". Tuttavia, questi punti di vista sono a volte così ridicolmente trincerati da eliminare quasi ogni tipo di deviazioni algoritmiche o di struttura dei dati dalla più pura implementazione "ingenua" ... o almeno da qualsiasi deviazione dal modo in cui sono " Ho già fatto cose prima. Come si può avvicinare le persone in questo modo in modo da far loro "aprire le orecchie" di nuovo dopo aver interrotto l'ascolto delle "prestazioni" o "ottimizzazione"? Come discuto un argomento di design / implementazione che ha un impatto sulle prestazioni senza che le persone pensino immediatamente: "Questo tizio vuole passare due settimane su dieci righe di codice?"

Ora, la posizione di "se l'ottimizzazione è prematura e quindi malvagia" o meno ha già trattata qui così come negli altri angoli del Web , e è già stato discusso come riconoscere quando l'ottimizzazione è prematura e quindi cattiva , ma purtroppo ci sono ancora persone nel reale mondo che non è così aperto alle sfide per la loro fede nell'anti-ottimizzazione.

Tentativi precedenti

Alcune volte, ho provato a fornire la citazione completa di Donald Knuth per spiegare che "l'ottimizzazione prematura è male "↛" l'ottimizzazione è pessima ":

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%.

Tuttavia, quando si fornisce l'intera citazione, a volte queste persone diventano più convinte che quello che sto facendo è Premature Optimization ™ e scavare e rifiutare di ascoltare. È quasi come se la parola "ottimizzazione" li spaventi: in un paio di occasioni, sono stato in grado di proporre modifiche al codice effettive per migliorare le prestazioni senza che venisse posto il veto semplicemente evitando l'uso della parola "optimiz (e | ation)" ( e "performance" pure - anche quella parola è spaventosa) e invece usa espressioni come "architettura alternativa" o "implementazione migliorata". Per questo motivo, sembra davvero che questo sia veramente dogmatismo e non li valutano di fatto ciò che dico in modo critico e poi lo liquidano come non necessario e / o troppo costoso.

    
posta errantlinguist 12.04.2016 - 18:01
fonte

11 risposte

34

Sembra che tu stia cercando scorciatoie per non provare prima la "pura implementazione naive" e implementare direttamente una "soluzione più sofisticata perché sai in anticipo che l'implementazione ingenua non lo farà". Sfortunatamente, raramente funzionerà - quando non hai fatti concreti o argomenti tecnici per dimostrare che l'implementazione ingenua è o sarà troppo lenta, probabilmente hai torto e cosa stai facendo è ottimizzazione prematura. E provare a litigare con Knuth è l'opposto di avere un dato di fatto.

Secondo la mia esperienza, dovrai prima mordere il proiettile e provare prima la "ingenua implementazione" (e probabilmente rimarrai stupito quanto spesso sia abbastanza veloce), o almeno farai una stima approssimativa del tempo di esecuzione , come:

"L'implementazione ingenua sarà O (n³), e n è più grande di 100.000, che verrà eseguita alcuni giorni, mentre l'implementazione non-così-naive verrà eseguita in O (n), che richiederà solo pochi minuti ".

Solo con questi argomenti a portata di mano puoi essere sicuro che la tua ottimizzazione non è prematura.

C'è solo IMHO un'eccezione da questo: quando la soluzione più veloce è anche la più semplice e pulita, allora dovresti usare la soluzione più veloce fin dall'inizio. L'esempio standard è quello di utilizzare un dizionario invece di un elenco per evitare codice loop non necessario per le ricerche o l'uso di una buona query SQL che ti dà esattamente il record di un risultato che ti serve, invece di un grande set di risultati che deve essere filtrato in seguito nel codice. Se si dispone di un caso del genere, non discutere sul rendimento - la performance potrebbe essere un beneficio aggiuntivo, ma probabilmente irrilevante, e quando ne parli, le persone potrebbero essere tentate di usare Knuth contro di te. Discuti su leggibilità, codice più corto, codice più pulito, manutenibilità - non c'è bisogno di "mascherare" nulla qui, ma perché quelli (e solo quelli) sono gli argomenti corretti qui.

Secondo la mia esperienza, il secondo caso è raro - più tipicamente si può implementare una soluzione semplice, ingenua che è meglio comprensibile e meno soggetta a errori rispetto a una più complicata, ma probabilmente più veloce.

Ovviamente, dovresti conoscere i requisiti e il caso d'uso abbastanza bene da sapere quali prestazioni sono accettabili e quando le cose diventano "troppo lente" agli occhi degli utenti. In un mondo ideale, otterresti una specifica formale delle prestazioni da parte del tuo cliente, ma nei progetti del mondo reale, la performance richiesta è spesso un'area grigia, qualcosa che i tuoi utenti ti diranno solo quando notano che il programma si comporta "troppo lentamente" in produzione. E spesso, questo è l'unico modo per scoprire quando qualcosa è troppo lento - il feedback degli utenti, e quindi non è necessario citare Knuth per convincere i tuoi compagni di squadra che la loro "ingenua implementazione" non è stata sufficiente.

    
risposta data 12.04.2016 - 18:49
fonte
18

Chiediti questo:

  • Il software NON soddisfa le specifiche di prestazione?
  • Il software presenta un problema di prestazioni?

Questi sono i motivi per ottimizzare. Quindi, se le persone si oppongono, mostra loro le specifiche e torna da loro e spiega che dobbiamo ottimizzare perché non stiamo incontrando le specifiche. Oltre a questo, si fatica a convincere gli altri che l'ottimizzazione è necessaria.

Penso che il punto principale della citazione sia, se non si ha un problema, non eseguire l'ottimizzazione inutile in quanto il tempo e l'energia potrebbero essere spesi altrove. Da un punto di vista aziendale, questo ha perfettamente senso.

Secondario, per coloro che temono l'ottimizzazione, eseguire sempre il backup dei risultati delle prestazioni con le metriche. Quanto più veloce è il codice? Quanto è migliorata la performance rispetto al passato? Se uno passasse due settimane solo per migliorare il codice del 2% rispetto alla versione precedente, se fossi il tuo capo non sarei felice. Queste due settimane avrebbero potuto essere spese per implementare una nuova funzionalità che potesse attirare più clienti e guadagnare di più.

Infine, la maggior parte dei software non deve essere altamente ottimizzata. Solo in alcune industrie specializzate la velocità è davvero importante. Quindi, la maggior parte delle volte si possono usare librerie e framework preesistenti con buoni risultati.

    
risposta data 12.04.2016 - 18:27
fonte
7

How to work with people who stonewall a discussion the minute it has to do with performance?

Inizia con principi condivisi che si basano sulla direzione strategica del tuo gruppo.

I miei principi:

I miei principi personali sulla scrittura del codice mirano innanzitutto alla correttezza nel mio programma, quindi al suo profilo e alla determinazione dell'ottimizzazione. Io registro il mio codice da solo perché altri programmatori sono potenziali consumatori del mio codice - e non lo userebbero se fosse lento - quindi per il mio codice, la velocità è una caratteristica.

Se i tuoi consumatori sono clienti, i tuoi clienti ti diranno se hai bisogno di un codice più veloce.

Tuttavia, ci sono conosciute, dimostrabilmente migliori scelte nel codice che si possono fare. Preferirei farlo bene nella mia prima bozza per diversi motivi:

  1. Se ho capito bene la prima volta, posso dimenticare l'implementazione (sfruttando il nascondiglio delle informazioni) e non ingombrare il mio codice con TODO.
  2. Gli altri (in particolare quelli che imparano solo sul lavoro) lo vedono fatto nel modo giusto, e imparano da e usano lo stesso stile di codice in futuro. Al contrario, se mi vedono farlo nel modo sbagliato, lo faranno anche nel modo sbagliato.

Supponendo che la necessità di ottimizzazione sia corretta

Supponendo che questa sia una parte veramente importante del tuo codice che ha bisogno di ottimizzazione, potresti dire la parabola di Schlemiel the Painter o enfatizzi il resto della citazione:

"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. 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%." - Donald Knuth

Pesare i costi di complessità aggiuntiva

A volte c'è un costo reale in termini di manutenibilità della complessità aggiunta. In questo caso, potresti mantenere l'implementazione secondaria in una diversa funzione o sottoclasse e applicare le stesse unittest ad essa in modo che non ci sia dubbio che sia corretta. Successivamente, se profili il tuo codice e scopri che l'implementazione ingenua è un collo di bottiglia, puoi inserire il codice ottimizzato e migliorare in modo dimostrabile il tuo programma.

Leadership

A volte il problema è l'ego - alcune persone preferiscono usare un codice subottimale o buggato piuttosto che qualcun altro sia più giusto di loro. Probabilmente vuoi evitare di lavorare con queste persone.

La leadership, specialmente quando non si ha autorità posizionale sulle persone, si tratta di dare suggerimenti ragionevoli e guidare gli altri a un consenso. Se non riesci a guidare la tua squadra a un incontro delle menti, forse la questione non vale la pena. Probabilmente c'è un pesce più grosso da friggere.

    
risposta data 12.04.2016 - 18:32
fonte
6

La via da seguire è quella di dimenticare la citazione attuale e le varie interpretazioni - il dogmatismo in entrambi i casi si concentra così tanto su una specifica citazione di un guru. Chi dice che Knuth ha sempre ragione comunque?

Concentrati invece sul progetto, il software che sviluppi insieme ai colleghi con cui non sei d'accordo. Quali sono i requisiti per le prestazioni accettabili per questo software? È più lento di questo? Quindi ottimizzare.

Non devi chiamarlo "ottimizzazione", puoi chiamarlo "correggere un bug", poiché è per definizione un bug se l'implementazione non è conforme ai requisiti.

Più in generale, ci sono due possibilità per quanto riguarda le ottimizzazioni:

  1. Il codice ottimizzato è anche più breve, più semplice da capire e più facile da mantenere.

  2. Il codice ottimizzato è più complesso da comprendere, richiede più tempo tempo di scrivere e testare, o sarebbe più complesso cambiare in futuro se i requisiti cambiano in modi imprevisti.

Se il caso è (1) non devi nemmeno discutere sull'ottimizzazione. Ma se (2) è il caso, allora stai prendendo una decisione di trade-off . Questa è in realtà una decisione a livello aziendale, non solo una decisione tecnica. Devi valutare il costo dell'ottimizzazione rispetto al vantaggio. Affinché ci sia anche un vantaggio, l'inefficienza deve essere un problema, in primo luogo, come esperienza utente negativa o costo significativamente maggiore dell'hardware o di altre risorse.

    
risposta data 12.04.2016 - 18:21
fonte
4

Penso che la citazione completa nel contesto sia istruttiva. Copierò da un post che ho fatto su Reddit sull'argomento:

There is no doubt that the grail of efficiency leads to abuse. Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. 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, Programmazione strutturata con go to Statements , ACM Computing Surveys, Vol. 6, No. 4, dic. 1974, p.268

Il punto, e l'implicazione, è che ci sono cose più importanti di cui preoccuparsi piuttosto che mettere troppo presto l'attenzione sull'ottimizzazione. Certo, dovresti considerare attentamente le tue strutture dati e gli algoritmi (questo è nel 3%) ma non dovresti preoccuparti se la sottrazione è più veloce di modulo (questo è nel 97%) finché non diventa chiaro che basso l'ottimizzazione del livello è necessaria.

Il primo non è necessariamente un'ottimizzazione nel senso che i tuoi colleghi stanno pensando, ma è un'ottimizzazione nel senso che algoritmi e strutture dati scarsamente scelti sono suboptimali

    
risposta data 12.04.2016 - 18:57
fonte
3

Nella mia esperienza, se ottieni questo tipo di opposizione all'ottimizzazione regolarmente , le persone non si lamentano in realtà dell'ottimizzazione. Si lamentano di ciò che stai sacrificando in nome dell'ottimizzazione. Di solito è leggibilità, manutenibilità o tempestività. Se il tuo codice viene consegnato nella stessa quantità di tempo, e altrettanto facile da capire, alla gente non potrebbe importare di meno se stai usando strutture dati e algoritmi più efficienti. Il mio suggerimento in questo caso è di lavorare per rendere il tuo codice più elegante e manutenibile.

Se stai ottenendo questo tipo di opposizione riguardo al codice degli altri, di solito è perché stai suggerendo una quantità significativa di rilavorazione. In questi casi hai davvero bisogno di alcune misure reali per dimostrare che ne vale la pena, o forse cercare di essere coinvolto prima nella fase di progettazione, prima che il codice venga scritto. In altre parole, è necessario dimostrare che è del 3%. Se avessimo riscritto tutto il codice che non era esattamente come ci piaceva, non avremmo mai ottenuto nulla.

    
risposta data 12.04.2016 - 19:07
fonte
2

Ci sono davvero molte incomprensioni su questa citazione, quindi è meglio fare un passo indietro e vedere quale sia il vero problema. Il problema non è tanto che non dovresti mai "ottimizzare". È che "ottimizzare" non è mai un compito che dovresti intraprendere. Non dovresti mai svegliarti al mattino e dire a te stesso "hey, dovrei ottimizzare il codice oggi!".

Questo porta a uno sforzo inutile. Basta guardare il codice e dire "Posso renderlo più veloce!" porta a un sacco di sforzi per fare qualcosa di più veloce che è stato abbastanza veloce in primo luogo. Potresti trovare l'orgoglio nel dirti che hai fatto un po 'di codice quattro volte più velocemente, ma se quel codice era un calcolo che si è verificato con una pressione di un pulsante, e ci sono voluti 10 msec in primo luogo prima di essere visualizzato da un utente umano, nessuno me ne frega un po '.

Questo è il "prematuro" in "ottimizzazione prematura". Quando non è "prematura"? Quando i clienti ti dicono "questo è troppo dannatamente lento, aggiustalo!" È quando digiti il codice e prova a renderlo più veloce.

Questo non significa che dovresti spegnere il tuo cervello. Ciò non significa che dovresti conservare 10.000 record di clienti in una lista concatenata. Dovresti sempre capire l'impatto delle prestazioni di ciò che fai in mente e agire di conseguenza. Ma l'idea è che non stai spendendo tempo extra cercando deliberatamente di renderlo più veloce. Stai semplicemente scegliendo la scelta più performante da scelte altrimenti uguali.

    
risposta data 12.04.2016 - 18:54
fonte
1

Puoi fare le cose nel modo sbagliato o fare le cose nel modo giusto.

Spesso, le cose sono fatte nel modo sbagliato e il codice è refactored in modo che sia fatto nel modo giusto. Se stai per scrivere un nuovo codice e sai che puoi fare le cose nel modo giusto senza una penalità maggiore, mi sbaglierei sul lato giusto nel farlo nel modo giusto. (Si noti che, dopo il test delle prestazioni, ecc., Alcune cose potrebbero dover essere cambiate - ma va bene. In alternativa, un'implementazione completamente ingenua è raramente, se non addirittura giusta.)

Non è necessariamente l'ottimizzazione prematura se tu a) sai che aiuterà in futuro o b) sappi che il percorso subottimale porterà a problemi lungo la strada. È come un gioco di scacchi, davvero.

Penso che le persone tenderanno a voler fare le cose per bene, piuttosto che sbagliarle. Usalo quando discuti di strategie alternative con i tuoi pari.

    
risposta data 12.04.2016 - 19:27
fonte
1

Questo sembra un problema di comunicazione e non un problema di programmazione. Cerca di capire perché le persone si sentono come loro e cercano di cristallizzare perché pensi che la tua strada sarebbe migliore. Quando hai finito, non iniziare una discussione conflittuale in cui il tuo obiettivo è quello di dire agli altri perché hanno torto e hai ragione. Spiega i tuoi pensieri e sentimenti e lascia che le persone reagiscano a quello. Se non riesci a raggiungere alcun tipo di consenso e ritieni che questo sia un problema davvero critico, probabilmente nel gruppo ci sono alcuni problemi gravi.

Più focalizzato sulla programmazione reale, non perdere tempo con lunghe discussioni su qualcosa che hai solo una sensazione istintiva "più veloce". Se vedi qualcuno che scrive un metodo chiamato una volta per richiesta in un'app web e ha complessità di tempo O (n ^ 2) quando SAPI che è davvero un problema di tempo O (log (n)), allora certo, se è così un gioco da ragazzi, vai avanti.

Attenzione però, come esseri umani, noi programmatori siamo davvero pessimi (e intendo AWFUL) a indovinare quali parti delle nostre applicazioni avranno un collo di bottiglia. Eric Lippert scrive su questo argomento interessante nel questo post del blog. Favorire sempre la manutenibilità. Eventuali problemi di prestazioni eventualmente riscontrati possono quindi essere facilmente risolti (beh, relativamente) quando si hanno più informazioni.

    
risposta data 12.04.2016 - 18:10
fonte
-1

L'ottimizzazione è cattiva.

Utilizza l'ottimizzazione delle prestazioni. La messa a punto delle prestazioni rende tutti felici.

Si noti che l'ottimizzazione delle prestazioni non è senza scopo come "ottimizzazione", ma cerca deliberatamente aspetti della propria applicazione che oggettivamente non hanno prestazioni sufficienti e li migliorano con risultati misurabili.

Puoi anche rimuovere bug che portano a rallentamenti. Qual è il più delle volte ciò di cui hai bisogno; in molti casi pratici il tuo computer è abbastanza veloce da gestire qualsiasi cosa venga lanciato a meno che non ci sia un codice veramente stupido che lo trattiene .

    
risposta data 12.04.2016 - 18:23
fonte
-1

Le prestazioni del codice non sono l'unico argomento per modificare il codice. Il codice è più facile da capire quali sono le modifiche che proponi? Queste modifiche rendono il codice più facile da mantenere?

Se le prestazioni di un pezzo di codice non sono critiche rispetto alla manutenibilità e l'assenza di bug è spesso più importante.

    
risposta data 12.04.2016 - 21:34
fonte

Leggi altre domande sui tag