Quando "ottimizzare il codice" == "strutturare i dati"?


9

Un recente articolo di ycombinator elenca un commento con i principi di un grande programmatore.

#7. Buon programmatore: ottimizzo il codice. Migliore programmatore: strutturo i dati. Miglior programmatore: qual è la differenza?

Riconoscendo concetti soggettivi e controversi - qualcuno ha una posizione su cosa significhi? Sì, ma vorrei modificare questa domanda in seguito con i miei pensieri in modo da non predisporre le risposte.


2
L'elenco di riferimento contiene un sacco di fantastici oggetti. Grazie.
Sviluppatore:

Questa domanda (che ho posto) ha una risposta che menziona anche questa citazione: programmers.stackexchange.com/q/168013/15028
TCSGrad

Risposte:


16

Nove volte su dieci, quando strutturi bene il tuo codice / modello, l'ottimizzazione diventerà ovvia. Quante volte hai visto nidificare un calabrone e lo hai trovato del tutto non ottimale, dove dopo averlo ristrutturato molti licenziamenti sono diventati estremamente evidenti.

Un designer sa di aver raggiunto la perfezione non quando non c'è più niente da aggiungere, ma quando non c'è più niente da togliere. - Antoine de Saint-Exupéry

Un sistema ben strutturato avrà un carattere minimo e, a causa della sua natura minima, sarà ottimizzato perché quanto poco c'è si riferisce direttamente a quanto poco fa per raggiungere il suo obiettivo.

Modifica: per spiegare il punto su cui gli altri hanno tolto questo, è anche del tutto accurato vedere l'affermazione come identificazione della relazione tra codice e dati. Tale relazione è quindi: se si modifica la struttura dei dati, sarà necessario modificare il codice per rispettare la struttura modificata. Se desideri ottimizzare il tuo codice, è probabile che dovrai modificare la struttura dei tuoi dati per rendere il tuo codice in grado di gestire i dati in modo più ottimale.

Detto questo, c'è una possibilità totalmente separata a cui si stava sfuggendo qui, e sarebbe che questo tipo che ha relazioni con YCombinator potrebbe riferirsi ai dati del codice AS nella tradizione dell'omoiconicità LISP. È una mia ipotesi supporre questo come il significato nella mia mente, ma è YCombinator, quindi non escluderei che la citazione stia semplicemente dicendo che i LISPer sono i "migliori programmatori".


1
Questo non parla di "dati" e di come "non vi sia differenza tra l'ottimizzazione del codice e la strutturazione dei dati". L'ottimizzazione del codice non ristruttura i dati errati a meno che non si tratti di una sorta di auto-digestione, turing-complete, macchina
New Alexandria

1
@NewAlexandria il modello menzionato è il "dato". Spesso codici errati e modelli cattivi vanno di pari passo. Riparare l'uno implica riparare l'altro.

1
@NewAlexandria Mi riferisco a strutturare i tuoi modelli come strutturando "dati", il mio punto è semplicemente che strutturare dati / codice sono sinonimi perché fanno parte del sistema nel suo insieme e interdipendenti. Per strutturare bene, occorreranno anche cambiamenti all'altro, forse questo è più di quello che stavi cercando? Stavo cercando di spiegare come la struttura e l'ottimizzazione siano uguali, non come il codice e i dati siano correlati, forse ho frainteso la tua domanda se quella fosse la parte confusa per te?
Jimmy Hoffa,

Penso che questo sia il più vicino a chiarire il senso corretto dell'argomento. Sapevo certamente come funzionava, ma speravo che qualcuno avesse visto qualcosa di più profondo nella domanda che avevo citato.
Nuova Alessandria,

4

Penso che l'autore suggerisca che qualsiasi ristrutturazione dei dati porta alla ristrutturazione del codice. Pertanto, la ristrutturazione dei dati con l'obiettivo di ottimizzare il sistema ti costringerà a ottimizzare anche il tuo codice, spingendo "qual è la differenza?" risposta.

Si noti che un "programmatore eccellente" può rispondere a "qual è la differenza?" che c'è ancora qualche differenza: una volta che ti avventuri nell'ottimizzazione per un migliore utilizzo della cache della CPU, puoi mantenere lo stesso layout delle tue strutture dati, ma cambiare l'ordine con cui accedervi può fare molto differenza.


Interessante punto di vista, ho avuto l'impressione che la similitudine tra struttura e ottimizzazione fosse l'argomento dell'affermazione, non la relazione tra codice e dati, sebbene tu abbia assolutamente ragione sulla relazione e che spieghi anche questo. Sembra di fare a pezzi un koan :)
Jimmy Hoffa,

A volte la ristrutturazione dei dati consente la ristrutturazione del codice, ma a volte penso che quando hai finito, il nuovo codice ha molto poco in comune con il vecchio codice.
Sviluppatore:

OTOH, l'allineamento dei dati per la dimensione della linea della cache può avere un grande impatto. ;-p
Macke

3

Considera l'esempio più ovvio di questo: "la ricerca di dati utente è troppo lenta!"

Se i dati dell'utente non sono indicizzati o almeno ordinati, la ristrutturazione dei dati produrrà rapidamente prestazioni del codice aumentate. Se i dati sono strutturati correttamente e stai solo scorrendo la raccolta (piuttosto che usare gli indici o fare qualcosa come una ricerca binaria), la modifica del codice produce un aumento delle prestazioni del codice.

I programmatori sono risolutori di problemi. Sebbene sia utile distinguere tra algoritmi e strutture dati, spesso non possono esistere isolatamente. I migliori programmatori lo sanno e non si isolano inutilmente.


1

Non sono d'accordo con l'affermazione sopra menzionata, almeno senza una spiegazione. Vedo che la codifica è l'attività che comporta l'utilizzo di alcune strutture di dati. Le strutture di dati influenzerebbero generalmente la codifica. Quindi c'è una differenza tra i due secondo me.

Penso che l'autore avrebbe dovuto scrivere l'ultima parte come "Miglior programmatore: ottimizzo entrambi".

C'è un grande libro (almeno lo era quando è stato pubblicato) chiamato: Algorithms + Data Structures = Programs .


0

L'ottimizzazione del codice a volte può migliorare la velocità di un fattore due e occasionalmente di un fattore dieci o addirittura venti, ma questo è tutto. Può sembrare molto, e se un 75% del tempo di esecuzione di un programma viene speso in una routine a cinque righe la cui velocità può essere facilmente raddoppiata, una tale ottimizzazione potrebbe valere la pena. D'altra parte, la selezione delle strutture di dati può influire sulla velocità di esecuzione di molti ordini di grandezza. Un moderno processore multi-thread iper-ottimizzato che esegue codice super-ottimizzato per cercare i dati per chiave in un elenco collegato lineare da 10.000.000 elementi archiviato nella RAM sarebbe più lento di un processore molto più lento che esegue una tabella hash nidificata piuttosto semplicemente codificata. In effetti, se si disponessero correttamente i dati, anche un 1980 '

Detto questo, la progettazione di strutture di dati efficienti richiede spesso compromessi più complessi rispetto all'ottimizzazione del codice. Ad esempio, in molti casi le strutture di dati che consentono l'accesso ai dati in modo più efficiente sono meno efficienti per l'aggiornamento (a volte per ordini di grandezza) rispetto a quelle che consentono aggiornamenti veloci e quelle che consentono gli aggiornamenti più veloci possono consentire l'accesso più lento. Inoltre, in molti casi, le strutture di dati che sono ottimali per insiemi di dati di grandi dimensioni possono essere relativamente inefficienti con quelle di piccole dimensioni. Un buon programmatore dovrebbe sforzarsi di bilanciare quei fattori in competizione con la quantità di tempo del programmatore necessario per implementare e mantenere varie strutture di dati ed essere in grado di trovare un equilibrio decente tra loro.


0

Le strutture di dati guidano molte cose relative alle prestazioni. Penso che possiamo esaminare i problemi duramente e a lungo con un'idea preconcetta sulla struttura dei dati ideale e, in questo contesto di pensiero, persino creare prove (spesso per induzione) di ottimalità. Ad esempio, se inseriamo un elenco ordinato in un array e valutiamo cose come il costo per inserire un elemento, potremmo decidere in media che dobbiamo spostare 1/2 dell'array per ogni inserimento. Per ogni ricerca binaria , possiamo trovare (o meno) un elemento corrispondente nei log n passaggi.

In alternativa, se rinviamo la nostra decisione sulla struttura dei dati (evitiamo l'ottimizzazione prematura ) e studiamo i dati in arrivo e il contesto in cui li utilizzeremo, quanto è grande, quali latenze si verificano e quali sono importanti per gli utenti, quanta memoria abbiamo vs. userebbe con rappresentazioni di dati che conosciamo o che possiamo escogitare.

In un'area come l'ordinamento e la ricerca, c'è molto da sapere. Davvero grandi programmatori ci hanno lavorato a lungo. Comprendere bene questi problemi è utile ed è un'ottima cosa se si conoscono più metodi rispetto a quando si è terminato il corso di laurea in strutture di dati. Gli alberi binari possono fornire prestazioni superiori per gli inserimenti in cambio di un uso maggiore della memoria. Le tabelle hash forniscono miglioramenti ancora maggiori, ma per una quantità maggiore di memoria. Un albero radix e un ordinamento radix possono apportare ulteriori miglioramenti.

La strutturazione creativa dei dati può aiutare a riformulare un problema e ad aprire le porte a nuovi algoritmi che rendono più veloci le applicazioni difficili e attività talvolta impossibili.


0

Per articolare la mia migliore ipotesi sul significato dell'articolo, supporrò un sottotesto non scritto (che sembra mancare nell'articolo) che qualsiasi programmatore dovrebbe capire sull'ottimizzazione:

  • l'ottimizzazione arriva solo dopo che il programma è attivo e funzionante correttamente:
    • farlo funzionare correttamente, quindi farlo funzionare velocemente
    • questo principio è il punto della massima di Knuth, "l'ottimizzazione prematura è la radice di tutti i mali"
  • se e quando hai stabilito che l'ottimizzazione non è prematura, devi prima misurarla correttamente per determinare ciò che effettivamente deve essere ottimizzato, e ancora e ancora durante l' ottimizzazione, per dire quali effetti stanno avendo i tuoi tentativi di ottimizzazione.
    • se il tuo codice viene eseguito in fase di sviluppo, il profiler è tuo amico in questo.
    • se il codice viene eseguito in produzione, è necessario strumentare il codice e fare amicizia con il sistema di registrazione.

Ora, quindi: le tue misurazioni ti diranno dove nel tuo codice la macchina sta bruciando più cicli. Un programmatore "buono" si concentrerà sull'ottimizzazione di quelle parti del codice, piuttosto che perdere tempo a ottimizzare le parti irrilevanti.

Tuttavia, è spesso possibile ottenere maggiori guadagni osservando il sistema nel suo insieme e trovando un modo per consentire alla macchina di svolgere meno lavoro. Spesso, queste modifiche richiedono una rielaborazione dell'organizzazione dei dati; quindi, un programmatore "migliore" si troverà a strutturare i dati più spesso.

Il "miglior programmatore" avrà un modello mentale approfondito di come funziona la macchina, una buona base nella progettazione di algoritmi e una comprensione pratica di come interagiscono. Ciò gli consente di considerare il sistema come un tutto integrato - non vedrà alcuna differenza tra l'ottimizzazione del codice e dei dati, poiché li valuta a livello di architettura.


-1

Miglior programmatore: qual è la differenza?

Il miglior programmatore? No. Programmatore scadente. Suppongo che la parola "ottimizzazione" significhi quelle cose che i programmatori in genere cercano di ottimizzare, tempo di memoria o CPU. In questo senso, l'ottimizzazione è in contrasto con quasi tutte le altre metriche del software. Comprensione, manutenibilità, testabilità, ecc .: tutto ciò richiede una breve deviazione quando l'obiettivo è l'ottimizzazione, a meno che ciò che si cerca di ottimizzare sia la comprensibilità umana, la manutenibilità, la testabilità, ecc. Per non parlare dei costi. Scrivere un algoritmo ottimale di velocità / spazio costa molto di più in termini di tempo di sviluppo rispetto alla codifica ingenua dell'algoritmo come presentato in alcuni testi o riviste. Un programmatore schifoso non conosce la differenza. Uno buono lo fa. Il miglior programmatore sa come determinare esattamente cosa deve essere ottimizzato e lo fa in modo giudizioso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.