Normalmente odio la parola "ottimizzazione prematura", ma questo puzza. Vale la pena notare che Knuth ha usato questa famosa citazione nel contesto del push per usare le goto
istruzioni al fine di accelerare il codice in aree critiche . Questa è la chiave: percorsi critici .
Stava suggerendo di usare goto
per accelerare il codice ma avvertendo contro quei programmatori che vorrebbero fare questo tipo di cose sulla base di intuizioni e superstizioni per il codice che non è nemmeno critico.
Favorire le switch
dichiarazioni il più possibile uniformemente in una base di codice (indipendentemente dal fatto che venga gestito o meno un carico pesante) è il classico esempio di ciò che Knuth chiama il programmatore "scemo e sciocco" che trascorre tutto il giorno a lottare per mantenere il proprio "ottimizzato "codice che si è trasformato in un incubo di debug a seguito del tentativo di risparmiare centesimi di sterline. Tale codice è raramente gestibile e tanto meno efficiente anche in primo luogo.
Ha ragione?
Ha ragione dal punto di vista dell'efficienza di base. Nessun compilatore che io sappia può ottimizzare il codice polimorfico che coinvolge oggetti e invio dinamico meglio di un'istruzione switch. Non finirai mai con una LUT o salti la tabella al codice incorporato dal codice polimorfico, poiché tale codice tende a fungere da barriera di ottimizzazione per il compilatore (non saprà quale funzione chiamare fino al momento in cui il dispacciamento dinamico si verifica).
È più utile non pensare a questo costo in termini di tabelle di salto, ma più in termini di barriera di ottimizzazione. Per il polimorfismo, la chiamata Base.method()
non consente al compilatore di sapere quale funzione finirà per essere chiamata se method
è virtuale, non sigillata e può essere ignorata. Dal momento che non sa quale funzione verrà effettivamente chiamata in anticipo, non può ottimizzare la chiamata di funzione e utilizzare più informazioni nel prendere decisioni di ottimizzazione, dal momento che in realtà non sa quale funzione verrà chiamata in l'ora in cui il codice viene compilato.
Gli ottimizzatori sono al meglio quando possono scrutare una chiamata di funzione ed effettuare ottimizzazioni che appiattiscono completamente il chiamante e chiamano, o almeno ottimizzano il chiamante per lavorare in modo più efficiente con il chiamante. Non possono farlo se non sanno quale funzione verrà effettivamente chiamata in anticipo.
Sta solo parlando il culo?
L'uso di questo costo, che spesso equivale a centesimi, per giustificare la trasformazione in uno standard di codifica applicato in modo uniforme è generalmente molto sciocco, soprattutto per i luoghi che hanno un bisogno di estensibilità. Questa è la cosa principale da tenere d'occhio con i veri ottimizzatori prematuri: vogliono trasformare i problemi di prestazioni minori in standard di codifica applicati uniformemente in una base di codice, senza riguardo per la manutenibilità di sorta.
Mi offendo un po 'la citazione del "vecchio hacker C" usata nella risposta accettata, dato che sono una di quelle. Non tutti coloro che hanno codificato per decenni a partire da hardware molto limitato si sono trasformati in un ottimizzatore prematuro. Eppure ho incontrato e lavorato anche con quelli. Ma quei tipi non misurano mai cose come errori di filiale o mancati riscontri nella cache, pensano di conoscerli meglio e basano le loro nozioni di inefficienza in una complessa base di codice di produzione basata su superstizioni che non valgono oggi e talvolta non sono mai state vere. Le persone che hanno davvero lavorato in settori critici per le prestazioni spesso capiscono che l'ottimizzazione efficace è un'efficace definizione delle priorità, e cercare di generalizzare uno standard di codifica degradante della manutenibilità per risparmiare centesimi è un'assegnazione delle priorità molto inefficace.
I penny sono importanti quando si ha una funzione economica che non fa così tanto lavoro, che viene chiamata un miliardo di volte in un ciclo molto stretto e critico per le prestazioni. In tal caso, finiamo per risparmiare 10 milioni di dollari. Non vale la pena radere centesimi quando hai una funzione chiamata due volte per la quale il solo corpo costa migliaia di dollari. Non è saggio passare il tempo a contrattare sui penny durante l'acquisto di un'auto. Vale la pena contrattare per centesimi se si acquista un milione di lattine di soda da un produttore. La chiave per un'ottimizzazione efficace è comprendere questi costi nel loro giusto contesto. Qualcuno che cerca di risparmiare centesimi su ogni singolo acquisto e suggerisce che tutti gli altri cercano di contrattare sui penny, indipendentemente da ciò che stanno acquistando, non è un abile ottimizzatore.