TD; DR:
C'era un po 'di confusione su ciò che stavo chiedendo, quindi ecco l'idea alla base della domanda:
Ho sempre voluto che la domanda fosse quella che è. Potrei non averlo articolato bene in origine. Ma l'intento è sempre stato " è un codice modulare, separato, accoppiato, disaccoppiato, refactored " marcatamente più lento per sua natura rispetto al codice " monolitico unità singola, fare tutto in un posto, un file, strettamente accoppiato ". Il resto sono solo dettagli e varie manifestazioni di questo che mi sono imbattuto allora o ora o lo farò più tardi. È sicuramente più lento su una certa scala. Come un disco non deframmentato, devi raccogliere i pezzi da ogni parte. È più lento. Di sicuro. Ma dovrei preoccuparmi?
E la domanda non riguarda ...
non si tratta di micro-ottimizzazione, ottimizzazione prematura, ecc. Non si tratta di "ottimizzare questa o quella parte fino alla morte".
Quindi cos'è?
Riguarda la metodologia generale e le tecniche e i modi di pensare alla scrittura del codice emersi nel tempo:
- "inserisci questo codice nella tua classe come dipendenza"
- "scrivi un file per classe"
- "separa la tua vista dal tuo database, controller, dominio".
- non scrivere spaghetti omogenei a codice singolo, ma scrivere molti componenti modulari separati che lavorano insieme
Riguarda il modo e lo stile del codice che è attualmente - entro questo decennio - visto e sostenuto nella maggior parte dei framework, sostenuto nelle convenzioni, trasmesso attraverso la comunità. È un passaggio nel pensare dai "blocchi monolitici" ai "microservizi". E da ciò deriva il prezzo in termini di prestazioni e sovraccarico a livello di macchina, e anche alcune spese generali a livello di programmatore.
Segue la domanda originale:
Nel campo dell'Informatica, ho notato un notevole cambiamento nel modo di pensare quando si tratta di programmazione. Mi capita spesso di vedere il consiglio che va così:
- scrivere un codice più piccolo dal punto di vista funzionale (più testabile e gestibile in questo modo)
- rielaborare il codice esistente in blocchi di codice sempre più piccoli fino a quando la maggior parte dei metodi / funzioni sono lunghi solo poche righe ed è chiaro qual è il loro scopo (che crea più funzioni rispetto a un blocco monolitico più grande)
- scrivere funzioni che fanno solo una cosa: separazione delle preoccupazioni, ecc. (che di solito crea più funzioni e più frame in una pila)
- creare più file (una classe per file, più classi a fini di decomposizione, per scopi di livello come MVC, architettura di dominio, modelli di progettazione, OO, ecc., che crea più chiamate al file system)
Questo è un cambiamento rispetto alle pratiche di codifica "vecchie" o "obsolete" o "spaghetti" in cui hai metodi che si estendono su 2500 linee e grandi classi e oggetti divini che fanno tutto.
La mia domanda è questa:
quando la chiamata si riduce al codice della macchina, a 1 e 0, alle istruzioni di assemblaggio, ai piatti dell'HDD, dovrei essere preoccupato del fatto che anche il mio codice OO perfettamente separato dalla classe con varietà di funzioni e metodi refactored da piccoli a piccoli molto più spese generali?
Dettagli
Anche se non ho familiarità con il modo in cui il codice OO e le sue chiamate di metodo vengono gestiti in ASM alla fine, e come le chiamate DB e le chiamate del compilatore si traducono nel movimento del braccio dell'attuatore su un piatto HDD, ho qualche idea. Suppongo che ogni chiamata di funzione aggiuntiva, chiamata di oggetto o chiamata "#include" (in alcune lingue), generi un set aggiuntivo di istruzioni, aumentando così il volume del codice e aggiungendo vari overhead di "cablaggio del codice", senza l'aggiunta di codice "utile" . Immagino anche che si possano fare buone ottimizzazioni ad ASM prima che venga effettivamente eseguito sull'hardware, ma che l'ottimizzazione può fare anche solo così tanto.
Quindi, la mia domanda: quanto sovraccarico (nello spazio e nella velocità) fa codice ben separato (codice che è suddiviso in centinaia di file, classi e modelli di progettazione, ecc.) Effettivamente introdotto rispetto ad avere "un grande metodo che contiene tutto in un unico file monolitico ", a causa di questo sovraccarico?
AGGIORNAMENTO per chiarezza:
Suppongo che prendere lo stesso codice e dividerlo, riformattarlo, disaccoppiarlo in sempre più funzioni e oggetti e metodi e classi comporterà il passaggio di un numero sempre maggiore di parametri tra pezzi di codice più piccoli. Perché di sicuro, il codice di refactoring deve mantenere attivo il thread e ciò richiede il passaggio di parametri. Più metodi o più classi o più modelli di progettazione di Metodi di fabbrica, si traducono in un sovraccarico maggiore nel passaggio di vari bit di informazioni più di quanto non avvenga in una singola classe o metodo monolitico.
È stato detto da qualche parte (citazione da TBD) che fino al 70% di tutto il codice è costituito dall'istruzione MOV di ASM: caricare i registri della CPU con le variabili appropriate, non il calcolo vero e proprio. Nel mio caso, si carica il tempo della CPU con le istruzioni PUSH / POP per fornire il collegamento e il passaggio dei parametri tra vari pezzi di codice. Più piccolo rendi le tue parti di codice, maggiore sarà il "collegamento" ambientale. Sono preoccupato che questo collegamento si aggiunga al gonfiore e al rallentamento del software e mi chiedo se dovrei preoccuparmi di questo e quanto, se non del tutto, perché le generazioni attuali e future di programmatori che stanno costruendo software per il prossimo secolo , dovrà convivere e consumare software creato utilizzando queste pratiche.
AGGIORNAMENTO: più file
Sto scrivendo un nuovo codice ora che sta lentamente sostituendo il vecchio codice. In particolare ho notato che una delle vecchie classi era un file di ~ 3000 righe (come menzionato in precedenza). Ora sta diventando un insieme di 15-20 file situati in varie directory, inclusi i file di test e non incluso il framework PHP che sto usando per unire alcune cose. Stanno arrivando anche altri file. Quando si tratta di I / O su disco, il caricamento di più file è più lento rispetto al caricamento di un file di grandi dimensioni. Ovviamente non tutti i file vengono caricati, vengono caricati in base alle esigenze e esistono opzioni di memorizzazione nella cache del disco e di memorizzazione nella memoria, eppure credo che ciò loading multiple files
richieda una maggiore elaborazione rispetto loading a single file
alla memoria. Lo sto aggiungendo alla mia preoccupazione.
AGGIORNAMENTO: Dipendenza Iniettare tutto
Tornando a questo dopo un po '.. Penso che la mia domanda sia stata fraintesa. O forse ho scelto di fraintendere alcune risposte. Non sto parlando di microottimizzazione come alcune risposte hanno individuato, (almeno penso che chiamare ciò di cui sto parlando di microottimizzazione sia un termine improprio) ma del movimento di "Codice refactor per allentare l'accoppiamento stretto", nel suo insieme , ad ogni livello del codice. Sono venuto da Zend Con proprio di recente, dove questo stile di codice è stato uno dei punti cardine e centrali della convenzione. Separare la logica dalla vista, dalla vista dal modello, dal modello dal database e, se possibile, separare i dati dal database. Dipendenza: Inietti tutto, il che a volte significa semplicemente aggiungere un codice di cablaggio (funzioni, classi, piastra di caldaia) che non fa nulla, ma funge da punto di aggancio / aggancio, raddoppiando facilmente la dimensione del codice nella maggior parte dei casi.
AGGIORNAMENTO 2: La "separazione del codice in più file" influisce in modo significativo sulle prestazioni (a tutti i livelli di elaborazione)
In che modo la filosofia di compartmentalize your code into multiple files
impatto dell'elaborazione odierna (prestazioni, utilizzo del disco, gestione della memoria, attività di elaborazione della CPU)?
Io sto parlando di
Prima...
In un passato ipotetico ma non molto distante, potresti facilmente scrivere un monoblocco di un file che ha modello e visualizza e controlla spaghetti o non-spaghetti, ma che esegue tutto una volta che è già caricato. Facendo alcuni benchmark in passato usando il codice C ho scoperto che è MOLTO più veloce caricare in memoria un singolo file da 900 Mb ed elaborarlo in grossi pezzi piuttosto che caricare un mucchio di file più piccoli ed elaborarli in un pasto di pace più piccolo pezzi alla fine fanno lo stesso lavoro.
.. E adesso*
Oggi mi trovo a guardare il codice che mostra un libro mastro, che ha caratteristiche come ... se un articolo è un "ordine", mostra il blocco HTML dell'ordine. Se un elemento pubblicitario può essere copiato, stampa il blocco HTML che visualizza un'icona e i parametri HTML dietro di esso che consente di effettuare la copia. Se l'elemento può essere spostato verso l'alto o verso il basso, visualizzare le frecce HTML appropriate. Ecc. Posso, tramite Zend Framework, crearepartial()
chiamate, che essenzialmente significa "chiama una funzione che accetta i tuoi parametri e li inserisce in un file HTML separato che chiama anche". A seconda di quanto dettagliato desidero ottenere, posso creare funzioni HTML separate per le parti più piccole del libro mastro. Uno per freccia su, freccia giù, uno per "posso copiare questo elemento", ecc. Crea facilmente diversi file solo per visualizzare una piccola parte della pagina web. Prendendo il mio codice e il codice Zend Framework dietro le quinte, il sistema / stack probabilmente chiama circa 20-30 file diversi.
Che cosa?
Sono interessato agli aspetti, all'usura della macchina che viene creata compartimentando il codice in molti file separati più piccoli.
Ad esempio, caricare più file significa trovarli in vari punti del file system e in vari punti dell'HDD fisico, il che significa più tempo di ricerca e lettura dell'HDD.
Per CPU probabilmente significa più cambio di contesto e caricamento di vari registri.
In questo sottoblocco (aggiornamento n. 2) sono interessato più strettamente al modo in cui l'utilizzo di più file per svolgere le stesse attività che potrebbero essere eseguite in un singolo file, influisce sulle prestazioni del sistema.
Utilizzo dell'API Zend Form vs HTML semplice
Ho usato l'API Zend Form con le più recenti e moderne pratiche OO, per creare un modulo HTML con convalida, trasformandolo POST
in oggetti di dominio.
Mi ci sono voluti 35 file per farlo.
35 files =
= 10 fieldsets x {programmatic fieldset + fieldset manager + view template}
+ a few supporting files
Tutto ciò potrebbe essere sostituito con alcuni semplici file HTML + PHP + JS + CSS, forse un totale di 4 file leggeri.
È meglio? Ne vale la pena? ... Immagina di caricare 35 file + numerosi file di libreria Zend Zramework che li fanno funzionare, contro 4 semplici file.