Potrei essere di parte lavorando in aree molto critiche per le prestazioni come l'elaborazione delle immagini e il raytracing, ma direi comunque di ottimizzare "il più tardi possibile" . Indipendentemente da quanto siano importanti le tue esigenze in termini di prestazioni, dopo aver misurato, ci sono sempre più informazioni e chiarezza a posteriori, che in anticipo, il che significa che anche le ottimizzazioni più efficaci vengono in genere applicate in seguito dopo aver acquisito tale conoscenza.
Casi particolari
Ma a volte "il più tardi possibile" è ancora abbastanza dannatamente presto in alcuni casi particolari. Se parliamo di renderer offline, ad esempio, le strutture di dati e le tecniche utilizzate per raggiungere le prestazioni entrano effettivamente nella progettazione dell'utente finale. Ciò può sembrare disgustoso ma il campo è così all'avanguardia e così critico per le prestazioni che gli utenti accettano controlli di fine utente specifici per le tecniche di ottimizzazione applicabili a un particolare raytracer (ad esempio: cache di irradianza o mappatura dei fotoni), poiché alcuni di essi vengono utilizzati alle ore di attesa per il rendering di un'immagine, e altri sono abituati a distribuire enormi somme di denaro per affittare o possedere una fattoria di rendering con macchine dedicate al rendering. C'è una forte riduzione di tempo e denaro per quegli utenti se un renderizzatore offline competitivo può offrire una riduzione non banale del tempo impiegato per il rendering. Questa è una sorta di area in cui una riduzione del 5% nel tempo entusiasma davvero gli utenti.
In casi così particolari, non puoi semplicemente scegliere una tecnica di rendering volenti o nolenti e sperare di ottimizzarla in un secondo momento, poiché l'intero design, incluso il design end-user, ruota attorno alle strutture di dati e agli algoritmi che usi. Non puoi nemmeno semplicemente andare con ciò che ha funzionato bene per le altre persone da qui, tu, come individuo, e i tuoi particolari punti di forza e di debolezza, contribuisci pesantemente a fornire una soluzione competitiva. La mentalità e la sensibilità del principale sviluppatore dietro Arnold è diversa da quelle che lavorano su VRay che hanno utilizzato un approccio molto diverso; non possono necessariamente scambiare posti / tecniche e fare il miglior lavoro (anche se sono entrambi leader industriali). Devi tipo di esperimento, prototipo e benchmark e trovare quello che sei particolarmente bravo a fare dato la serie infinita di tecniche all'avanguardia là fuori se speri di spedire qualcosa di competitivo che effettivamente venderà. Quindi, in questo caso particolare, le preoccupazioni relative alle prestazioni si spostano molto in alto come forse la preoccupazione più importante prima di iniziare lo sviluppo.
Tuttavia, non si tratta necessariamente di una violazione dell'ottimizzazione "il più tardi possibile" , ma solo "il più tardi possibile" è piuttosto precoce in questi casi estremi e peculiari. Capire quando e anche ciò che non ha bisogno di tali problemi prestazionali, se non del tutto, è probabilmente la principale sfida per lo sviluppatore. Cosa non ottimizzare potrebbe essere una delle cose più preziose da imparare e continuare a imparare nella carriera di uno sviluppatore, dal momento che non c'è carenza di sviluppatori ingenui che vogliono ottimizzare tutto (e sfortunatamente anche alcuni veterani che sono riusciti in qualche modo a mantenere il loro lavoro in nonostante la loro contro-produttività).
Il più tardi possibile
Forse la parte più difficile è cercare di capire cosa significa. Sto ancora imparando e sto programmando da quasi tre decenni. Ma soprattutto ora nel mio terzo decennio, sto iniziando a rendermi conto che non è così difficile. Non è scienza missilistica, se ti concentri più sul design che sull'implementazione. Più i tuoi progetti lasciano spazio alle ottimizzazioni appropriate in un secondo momento senza modifiche al design, più tardi puoi ottimizzare. E la produttività sempre maggiore che ho guadagnato alla ricerca di tali progetti che mi offrono quel respiro.
Design che offre spazio di respirazione per ottimizzare in seguito
Questi tipi di progetti in realtà non sono così difficili da realizzare nella maggior parte dei casi se possiamo applicare un po 'di "buon senso". Come storia personale mi piacciono le arti visive come un hobby (trovo che aiuti in qualche modo a programmare software per gli artisti che sono in qualche modo me stesso per capire le loro esigenze e parlare la loro lingua), e ho trascorso un po 'di tempo nei primi anni 2000 usando le applet Oekaki online come un modo rapido per scarabocchiare e condividere il mio lavoro e connettersi con altri artisti.
In particolare il mio sito e la mia applet preferiti erano pieni di difetti prestazionali (qualsiasi dimensione del pennello non banale avrebbe rallentato a una scansione), ma aveva una comunità molto bella. Per aggirare i problemi di prestazione ho usato piccoli pennelli da 1 o 2 pixel e ho semplicemente scarabocchiato il mio lavoro in questo modo:
Nel frattempo continuavo a dare all'autore dei suggerimenti software per migliorare le prestazioni, e notò che i miei suggerimenti erano di natura particolarmente tecnica parlando di ottimizzazioni della memoria e algoritmi e così via. Quindi in realtà mi ha chiesto se fossi un programmatore e ho detto di sì e mi ha invitato a lavorare sul codice sorgente.
Quindi ho guardato il codice sorgente, l'ho eseguito, profilato, e con mio orrore aveva progettato il software attorno al concetto di "interfaccia pixel astratta", come IPixel
, che alla fine è stata la causa principale dietro i migliori hotspot per tutto con dinamica allocazioni e invio per ogni singolo pixel di ogni singola immagine. Eppure non c'era modo pratico per ottimizzarlo senza riconsiderare il design dell'intero software perché il design lo aveva intrappolato in un angolo in cui non c'è molto oltre la più banale delle micro-ottimizzazioni quando le nostre astrazioni funzionano al livello granulare di un singolo pixel astratto e tutto dipende da questo pixel astratto.
Penso che sia una violazione del "buon senso", ma ovviamente non è stato un tale buon senso per lo sviluppatore. Ma è come non astrarre cose a un livello così granulare in cui anche i casi d'uso più elementari verranno istanziati da milioni, come con pixel, o particelle, o piccole unità in una gigantesca simulazione dell'esercito. Favorisci IImage
(puoi gestire tutti i formati immagine / pixel di cui hai bisogno a quel livello aggregato più voluminoso) o IParticleSystem
verso IPixel
o IParticle
, e quindi puoi inserire le implementazioni più semplici e veloci da scrivere e da capire dietro tali interfacce e avere tutto lo spazio per respirare di cui avrete bisogno per ottimizzare in seguito senza riconsiderare il design dell'intero software.
E questo è l'obiettivo come lo vedo in questi giorni. Escludendo i casi particolari come i renderer offline di cui sopra, progettare con spazio sufficiente per l'ottimizzazione il più tardi possibile, con quante più informazioni di senno di poi possibile (comprese le misurazioni) e applicare tutte le ottimizzazioni necessarie il più tardi possibile.
Naturalmente non sto necessariamente suggerendo di iniziare a utilizzare algoritmi di complessità quadratica su input che raggiungono facilmente una dimensione non banale nei casi comuni dell'utente finale. Chi lo fa comunque? Ma non penso nemmeno che sia un grosso problema se l'implementazione è facile da scambiare in seguito. Questo non è ancora un grave errore se non è necessario riconsiderare alcun progetto.