2009-02-14 17 views
11

Pensi che vale la pena di negoziazione fuori alcune prestazioni per il codice di qualità e la manutenibilità? Ricordo un post di Jeff Atwood che affermava che l'hardware costa poco, gli sviluppatori no. Penso che mi piacerebbe cambiarlo in "L'hardware è economico, il tempo non lo è".Prestazioni rispetto della qualità del codice

Ho notato con un progetto MVC su cui ho lavorato ultimamente che a volte perdo GIORNI cercando di estrarre un po 'di prestazioni extra dalla mia app e sto iniziando a pensare che non ne valga la pena. Mi sono appena trovato in difficoltà con la progettazione di un'applicazione ASP.NET MVC. Amo IQueryable to death nel fatto che mi consente di aggiungere alla query in modo da poter ottenere un codice fluente per usarlo. Ma essere in grado di fare qualcosa del genere sembra aggiungere più responsabilità sul controller/BLL.

Quindi cosa ne pensi? Nel caso di applicazioni Web, sarebbe opportuno negoziare alcune prestazioni per codice mantenibile/pulito? Pensi che sia per cercare prematuramente di ottimizzare tutto ciò che puoi? Perché come abbiamo visto non è possibile prevedere tutti i requisiti.

risposta

16
  1. farlo funzionare
  2. Se le prestazioni sono discutibili, profilo e identificare il problema
  3. Risolvere il problema.
  4. Ripetere i passaggi 1-4 se necessario
  5. ???
  6. Profit
+1

Semplice, di solito le migliori risposte sono. –

+0

Il passaggio 5 è pura magia, è molto importante. –

+0

Dovrebbero essere 4 punti interrogativi, fratello! (hai appena perso il gioco) –

5

Io davvero non credo che questo è un o/o. Se scrivi un codice semplice e pulito che elabori tutte esattamente il numero di volte che dovrebbe, avrai il codice migliore che puoi. È davvero così semplice.

+0

Non stavo dubitando del fatto che non puoi averli entrambi. La domanda è stata davvero mirata a ritenere che valga la pena scambiare alcune prestazioni per l'altra ecc. Mi spiace di averlo scritto così male. –

+0

Faccio sempre finta di essere il mio cliente che sto progettando un'app per ... Finché funziona e funziona bene e che nessun altro guarda il codice a chi importa quanto sia pulito ... basta che lo sia funziona – dswatik

+0

commesso Touche. –

4

La risposta ovvia è dipende. Se la tua app è abbastanza lenta da influire in modo significativo sull'usabilità e hai misurazioni per dimostrare che le tue ottimizzazioni sono effettivamente d'aiuto, allora sacrificare la manutenibilità può essere un compromesso ragionevole. D'altra parte, se non hai misurato o l'app non è abbastanza lenta da ferire l'usabilità, cerca sempre leggibilità, manutenibilità e flessibilità. Questo si riduce all'ottimizzazione prematura essendo la radice di tutti i mali.

Nota: ottimizzazioni fase di progettazione algoritmici e architettoniche non sono necessariamente un male se si sa prestazioni sta andando alla materia per la vostra applicazione, ma nel caso della tua domanda, ti appaiono chiaramente a parlare di micro -ottimizzazione, a cui si applica quanto sopra.

Inoltre, nel caso specifico, se non si riesce a stabilire se l'app è abbastanza lenta da compromettere l'usabilità, è prematuro. Se puoi, allora non lo è.

+0

Immagino che questa sia la radice della mia domanda che modifico. Ottimizzazione prematura. –

0

Io sicuramente apprezzo il mio tempo durante le prestazioni delle applicazioni sul lato server. Se mi accorgo che il mio sito non funziona abbastanza bene su richieste al database, ecc, aggiornare l'hardware del server è una soluzione alternativa che potrebbe (almeno a breve termine) risolvere il mio problema senza guardare il codice.

Tuttavia, se l'applicazione è estremamente rete -inefficient, vorrei spendere un po 'di tempo a cercare di migliorare quella parte. L'invio di grandi quantità di dati colpisce miei utenti, non importa quello che faccio con il mio server e uplink - e se non piace la performance, non tornerà.

Ma, come molti altri hanno detto, non è una questione di o/o - dipende molto dalla situazione, come pesante è il problema di prestazioni, in cui l'applicazione ecc

1

Né la qualità (che significa facile leggere) né le prestazioni sono le più importanti - LA CORRETTEZZA è!

+0

Cosa succede se l'errore è minore e si verifica solo in alcuni casi limite? Un esempio ipotetico potrebbe essere un problema estetico che richiederebbe un sacco di logica del caso speciale o una piccola quantità di errore di arrotondamento in una funzione matematica. IMHO, anche la correttezza non è una vacca sacra che è immune ai compromessi. – dsimcha

+0

Quindi non ti importa se il codice che la tua banca usa per calcolare l'interesse del tuo account scende qualche dollaro qua e là? –

+0

Beh, questo non passerebbe come errata "minore". Non mi dispiacerebbe se la formattazione del sito web della mia banca apparisse un po 'approssimativa una volta ogni tanto se ciò significasse più caratteristiche, migliori prestazioni, passando sui costi di sviluppo abbassati come tassi di interesse più alti, ecc. Le banche non usano comunque il floating point. – dsimcha

12

Sir Tony Hoare ha detto, "Dobbiamo dimenticare le piccole efficienze, diciamo circa il 97% delle volte: l'ottimizzazione prematura è la radice di tutti i mali."

La prima parte della citazione è stata quasi dimenticata (non si stacca facilmente la lingua) e quindi molti ingegneri inesperti non prendono in considerazione le prestazioni durante la fase di progettazione di un progetto software. Questo è quasi sempre un errore fatale, poiché in seguito un'applicazione mal progettata è molto difficile da ottimizzare a causa di difetti di progettazione fondamentali. Allo stesso tempo, non ha senso cercare di salvare i cicli della CPU usando trucchi intelligenti quando i colli di bottiglia delle prestazioni non sono ancora noti.

Per quanto riguarda la tua domanda, penso che un'applicazione progettata correttamente per soddisfare i suoi particolari requisiti di prestazioni non debba essere codificata in modo non gestibile o "non pulito". È solo quando vengono scoperti i colli di bottiglia delle prestazioni (ad esempio, scopri che l'applicazione impiega il 90% del tempo nel 10% del codice) che potresti voler considerare con parsimonia utilizzando trucchi di ottimizzazione in piccole quantità del codice, in modo che rimanga manutenibile e facile da capire.

La cosa grandiosa di molte applicazioni Web è che le prestazioni possono essere drasticamente migliorate utilizzando varie tecniche di memorizzazione nella cache. Mentre controlli l'ambiente del server (e, come dici tu, l'hardware costa poco) puoi assicurarti di nasconderlo fuori da quelle parti di uso comune della tua app Web. Questo non rende davvero il codice non mantenibile se si utilizza un livello di astrazione. Facebook è un buon esempio di un'applicazione Web che sfrutta notoriamente il caching (memcached) a proprio vantaggio.

+0

Ottima risposta, grazie. –

+0

La prima parte viene dimenticata perché il 97% in quel momento è diventato il 99,9% ora. – Paco

1

D'accordo con questo in misura. Il tempo di sviluppo è costoso, e il profiling e l'ottimizzazione del codice è un modo molto costoso per ottenere probabilmente non un guadagno di prestazioni molto elevato. Detto ciò dipende dal tipo di applicazione e dall'ambiente in cui stai lavorando.

Se stai lavorando su un'applicazione web, puoi apportare enormi miglioramenti risolvendo alcuni semplici problemi (principalmente sul client -lato). Cose come la riduzione delle richieste HTTP concatenando i file CSS/JS, la costruzione di sprite di immagini, ecc ... ti daranno enormi vantaggi rispetto al codice di profilazione reale e sono un ottimo uso del tempo di sviluppo.

Non so che sono d'accordo con l'offerta "L'hardware è più economico rispetto agli sviluppatori". Ovviamente l'hardware può aiutarti a ridimensionare la tua applicazione e darle una maggiore quantità di prestazioni, ma l'ultima cosa che vuoi fare è contare su hardware robusto. Se il tuo software è troppo strettamente connesso all'hardware, perdi molta flessibilità in termini di passaggio a nuovi data center, upgrade di server, ecc ... e non avere quella flessibilità può essere molto costoso a lungo termine. Supponiamo che tu decida che il modo di scalare la tua applicazione in modo efficiente sia quello di passare all'infrastruttura EC2 di Amazon. Se la tua applicazione richiede 32 GB di RAM su ciascun server che stai per trovare una mossa come questa potrebbe richiedere una riscrittura.

2

Tutte buone risposte. La scelta tra velocità e codice pulito è una falsa dicotomia.

non ho visto lavorare, ma ho guardato gli altri, ed è sempre la stessa storia:.

"Non è abbastanza veloce Credo che il problema è nel codice XXX.Penso che tweak che e vedere se aiuta."

  • non ti conoscono il problema è lì.
    Stai indovinare.

  • mai nulla basata su una congettura .
    (Naturalmente si non lo farebbe mai, vero? Ma la maggior parte della gente.)

Si potrebbe profilare il codice.

Il mio metodo preferito è fermarlo un paio di volte mentre è lento e chiedergli cosa diavolo sta facendo.

Di solito è una sorpresa che non si poteva immaginare.

0

Una definizione standard di qualità è "Conformità alle aspettative del cliente (requisito)". Se hai fatto una buona raccolta di requisiti, allora hai accettato determinati criteri di rendimento. Se la tua domanda soddisfa questi criteri, stai sprecando il tuo, o il cliente, tempo e denaro cercando di fare meglio.

Scrittura di codice liberamente accoppiato, coeso e di facile lettura, riduce il rischio e il costo associati a bug e modifiche ai requisiti. Se sei pronto ad accettare il rischio della codifica "palla di fango", allora vai avanti. Io, mi piace realizzare un profitto.

2

Prima di parlare delle prestazioni dovresti davvero imparare a conoscere la notazione O grande, puoi trovarlo in qualsiasi libro sugli algoritmi o su wikipedia.

Big O notation dice qualcosa su quanto tempo impiega una funzione. Per esempio. Una lista che va da 0 a 100 hai O (N). Indipendentemente dal numero elevato che contate per la notazione O, rimane lo stesso. Questa funzione ha un runtime lineare e non può essere migliorata in alcun modo.

Ora se si dispone di un elenco in esecuzione da 0 a 100 e per ogni elemento in tale elenco si fa un altro elenco in esecuzione da 0 a 100 si ottiene O (N^2) che è il doppio del lavoro e ha un runtime molto peggio di O (N).

Quando scriviamo applicazioni che devono avere buone prestazioni, parliamo di ottenere un buon runtime scritto in notazione O. Se una finestra utilizza < 0,1 secondi o> 1 secondo non importa se utilizzano gli stessi algoritmi.

Ciò significa che la rasatura dei secondi che si esegue probabilmente non ha una notazione O differente, quindi non si sta veramente ottimizzando il codice in alcun modo. Quindi, per te, scrivere MVC in asp.net ti consiglierei concentrarsi invece sulla scrittura di codice pulito e leggibile :)

Quando si è a conoscenza della notazione O, sarà possibile sapere quali algoritmi scegliere (come ordinare gli elenchi, popolarli, recuperare i dati) in un modo che utilizza il minimo esegui il tempo in notazione O e questa conoscenza renderà proabably il tuo codice molto più velocemente di quanto si possa fare a pochi secondi dal tuo codice scrivendo loop stretti.

Makach ^^

0

buon design spesso sacrifica alcune prestazioni per il miglioramento del programma complessivo.Ad esempio, scrivere il codice nei livelli ha un costo, ma lo facciamo comunque perché rende più facile la modifica del codice a lungo termine. Usiamo i server delle app da remoto, non perché sia ​​il modo più efficiente, ma perché si ridimensiona.

Ricordo da Code Complete 2, McConnell fornisce un esempio in cui rendere il codice orribilmente difficile da leggere era necessario come ottimizzazione. Questo particolare esempio era un algoritmo di crittografia. Il programma è stato realizzato in un unico metodo per eliminare l'overhead di chiamare una funzione. Quindi, c'è davvero un tempo e un luogo per questo, ma credo che sia raro.

Per quanto riguarda la risoluzione dei problemi di prestazioni, nella maggior parte dei casi, ho riscontrato problemi di prestazioni da database o I/O o da (perdita di memoria). Come altri hanno suggerito, la profilazione è la strada da percorrere, anche se può ancora essere complicato rintracciare molti bug.

Per quanto riguarda il problema hardware, l'hardware si distende ma non elimina la necessità di codice ottimizzato. L'hardware più veloce ci consente davvero di usare linguaggi meno ottimali e fare cose GUI davvero belle.

0

Questo è uno dei classici compromessi tra prestazioni e supporto. Per prima cosa ho trovato questo scambio quando scrivevo il codice strutturato COBOL (nei primi anni '80). È diventato chiaro che separando tutto in moduli riutilizzabili è stato possibile creare branching extra e gestire il puntatore dello stack e sui primi computer questa prestazione degradata. La risposta consisteva nel raggruppare le funzioni (e duplicare alcune funzioni) al fine di ridurre lo scambio di codice e impilare le manipolazioni del puntatore utilizzate per chiamare i moduli. Ciò ha causato un problema di supporto.

Passando, più recentemente, ho dovuto de-normalizzare un database per creare oggetti di grandi dimensioni che potrebbero essere memorizzati nella cache. Il problema qui era la lettura dei diritti di accesso per ruoli e responsabilità durante la navigazione attorno a un sistema CRM. Per farla breve, la versione normalizzata ha impiegato troppo tempo per elaborare e caricare ogni schermata, quindi per 30 anni sono ancora coinvolto in questo classico compromesso.

Problemi correlati