Per me è spesso più produttivo sbagliare dal lato dell'ottimizzazione con il senno di poi, semplicemente schiaffo in un'implementazione di base che è facile da ragionare in termini di correttezza e rivisitazione secondo necessità con il profiler in mano. Preferisco scorrere a soluzioni più rapide quando possibile / pratico perché mi piace vedere il mio sistema sbrigarsi prima anche se devo tornare indietro e approfondire e sintonizzarlo in aree chiave.
Ma ho bisogno di mettere molta enfasi sulla parte pratica , poiché non è che tu possa scrivere un software il cui design ruota attorno all'interazione con oggetti teeny in uno scalare, uno alla volta moda, e si aspettano di trovare molto spazio per ottimizzarlo senza modificare il design. Non c'è bisogno di avere un'auto da corsa se ci sono solo 10 metri di strada da percorrere, e progettare interfacce eccessivamente granulari che trattano di cose piccanti, una volta alla volta, ti possono ingannare con un design che non lascia respiro spazio per l'ottimizzazione.
Quindi aiuta quando si anticipa un'area critica dal punto di vista delle prestazioni, che credo si possa anticipare spesso senza misurare *, per progettare interfacce sufficientemente grossolane, non granulari.
- As said I believe you can anticipate where the performance-critical parts are in your system reasonably well, even if you may not be able to anticipate the details fully until measuring. All you have to do is ask basic questions like, "where are we going to be looping over a million things"? Well, if you are implementing a GUI system, it's obvious where you'll be looping over a million things, and that'll be in the GUI drawing functions where you can potentially be looping over a million pixels to process. It's not unreasonable to deduce, in foresight, that this area is probably going to be a performance-critical so that you design it with sufficient breathing room to optimize and optimize it in the future.
Ad esempio, invece di far ruotare il tuo sistema sull'interazione con oggetti Pixel
granulari, disegnalo per interagire con collezioni di Pixels
con Image
oggetti che potrebbero rappresentare milioni di pixel contemporaneamente. Analogamente anziché Particle
oggetti, interagisci con ParticleSystem
. Invece di Creature
, interagisci con Creatures
. Invece di un callback che è progettato per elaborare una cosa teeny alla volta (un pixel alla volta, ad es.), Avere un callback che è progettato per elaborare una serie di cose alla volta (un intervallo di pixel alla volta). Questi tipi di cose ti lasceranno molto più respiro per ottimizzare senza modificare il design.
Librerie generiche
Detto questo, questo consiglio è rivolto a persone come te che vogliono andare avanti e affrontare grandi progetti. Se, per esempio, siete nella mentalità di progettare una biblioteca di strutture dati di uso generico le cui intenzioni devono essere quanto più largamente applicabili possibile, ed è fondamentalmente il prodotto finale, allora potreste risparmiare più tempo a pensare a come realizzarlo il più efficiente possibile in anticipo - ovviamente ancora misurando, sintonizzando e iterando mentre procedete, ma non semplicemente schiacciando un'implementazione di base se siete abbastanza sicuri che dovrete riscriverlo.
In questi casi, l'efficienza e l'applicabilità sono concetti correlati, dal momento che se la tua libreria è distorta in termini di prestazioni e manca di strutture dati a tutto tondo, le persone potrebbero non usarli così tanto o si potrebbe finire per sentire l'introduzione di sempre più dati le strutture durante la sintonizzazione delle precedenti potrebbero essere sufficienti. Quindi a volte può davvero pagare solo per cercare di ottenere la versione più efficiente che è possibile in anticipo. Nel corso degli anni ho scoperto che mi sono migliorato nell'ottimizzare il codice e in particolare per la località di riferimento che posso utilizzare usando sempre meno strutture di dati, finendo con strutture dati più complete che posso utilizzare in un contesto più ampio gamma di aree invece di quelle con caratteristiche di prestazione distorta che sono strettamente applicabili. Il risultato finale è molto meno codice per mantenere e migliorare la produttività, anche se è il risultato di una mentalità di ottimizzazione.