Ho spesso visto questa citazione usata per giustificare ovviamente codice o codice errato che, sebbene le sue prestazioni non siano state misurate, potrebbe probabilmente essere reso più veloce abbastanza facilmente, senza aumentare le dimensioni del codice o comprometterne la leggibilità.
In generale, penso che le prime micro-ottimizzazioni potrebbero essere una cattiva idea. Tuttavia, le macro-ottimizzazioni (cose come la scelta di un algoritmo O (log N) invece di O (N ^ 2)) sono spesso utili e dovrebbero essere fatte in anticipo, dal momento che potrebbe essere uno spreco scrivere un algoritmo O (N ^ 2) e quindi buttalo via completamente a favore di un approccio O (log N).
Nota le parole potrebbe essere : se l'algoritmo O (N ^ 2) è semplice e facile da scrivere, puoi buttarlo via più tardi senza troppi sensi di colpa se risulta troppo lento. Ma se entrambi gli algoritmi sono similmente complessi, o se il carico di lavoro previsto è così grande che sai già che avrai bisogno di quello più veloce, l'ottimizzazione anticipata è una decisione ingegneristica che ridurrà il tuo carico di lavoro totale a lungo termine.
Quindi, in generale, penso che l'approccio giusto sia scoprire quali sono le opzioni prima di iniziare a scrivere il codice e scegliere consapevolmente il miglior algoritmo per la tua situazione. Soprattutto, la frase "l'ottimizzazione prematura è la radice di tutti i mali" non è una scusa per l'ignoranza. Gli sviluppatori di carriera dovrebbero avere un'idea generale di quanto costano le operazioni comuni; dovrebbero sapere, per esempio,
- le stringhe costano più dei numeri
- le lingue dinamiche sono molto più lente delle lingue tipizzate staticamente
- i vantaggi degli elenchi array / vettoriali sugli elenchi concatenati e viceversa
- quando utilizzare un hashtable, quando usare una mappa ordinata e quando usare un heap
- che (se funzionano con dispositivi mobili) "double" e "int" hanno prestazioni simili sui desktop (FP può anche essere più veloce) ma "double" può essere cento volte più lento su dispositivi mobili di fascia bassa senza FPU;
- il trasferimento di dati su Internet è più lento dell'accesso all'HDD, gli HDD sono molto più lenti della RAM, la RAM è molto più lenta della cache e dei registri L1 e le operazioni Internet possono bloccarsi indefinitamente (e fallire in qualsiasi momento).
E gli sviluppatori dovrebbero avere familiarità con una cassetta degli attrezzi di strutture dati e algoritmi in modo che possano facilmente utilizzare gli strumenti giusti per il lavoro.
Avere un sacco di conoscenze e una cassetta degli attrezzi personale consente di ottimizzare quasi senza sforzo. Mettendo molto impegno in un'ottimizzazione che potrebbe non essere necessaria è male (e ammetto di cadere in quella trappola più di una volta). Ma quando l'ottimizzazione è facile come scegliere un set / hashtable anziché un array, o memorizzare un elenco di numeri in doppio [] invece di string [], perché no? Potrei essere in disaccordo con Knuth qui, non ne sono sicuro, ma penso che stesse parlando di ottimizzazione a basso livello mentre sto parlando di ottimizzazione ad alto livello.
Ricorda che la citazione è originaria del 1974. Nel 1974 i computer erano lenti e la potenza di calcolo era costosa, il che dava ad alcuni sviluppatori la tendenza a sovraottimizzare, linea per linea. Penso che sia quello contro cui Knuth stava spingendo. Non stava dicendo "non preoccuparti affatto delle prestazioni", perché nel 1974 sarebbe stato solo un pazzo parlare. Knuth stava spiegando come ottimizzare; in breve, uno dovrebbe concentrarsi solo sui colli di bottiglia, e prima di farlo è necessario eseguire misurazioni per trovare i colli di bottiglia.
Tieni presente che non riesci a trovare i colli di bottiglia fino a quando non hai scritto un programma su misura, il che significa che alcune decisioni relative alle prestazioni devono essere eseguite prima che esista qualcosa da misurare. A volte queste decisioni sono difficili da cambiare se si sbagliano. Per questo motivo, è utile avere un'idea generale delle cose che costano in modo da poter prendere decisioni ragionevoli quando non sono disponibili dati rigidi.
Quanto presto ottimizzare, e quanto preoccuparsi delle prestazioni dipende dal lavoro. Quando si scrivono script che verranno eseguiti solo poche volte, preoccuparsi delle prestazioni è in genere una completa perdita di tempo. Ma se lavori per Microsoft o Oracle e stai lavorando su una libreria che migliaia di altri sviluppatori utilizzeranno in migliaia di modi diversi, potrebbe essere utile per ottimizzare l'inferno, quindi che puoi coprire tutti i diversi casi d'uso in modo efficiente. Anche così, la necessità di prestazioni deve essere sempre bilanciata con la necessità di leggibilità, manutenibilità, eleganza, estensibilità e così via.