La micro-ottimizzazione è importante per la codifica?

170

Recentemente ho fatto una domanda su Stack Overflow per scoprire perché isset () era più veloce di strlen () in PHP . Ciò ha sollevato dubbi sull'importanza del codice leggibile e sul fatto che i miglioramenti delle prestazioni dei micro-secondi nel codice fossero degni di considerazione.

Mio padre è un programmatore in pensione e gli ho mostrato le risposte. Era assolutamente certo che se un programmatore non considera le prestazioni nel proprio codice anche a livello micro, non sono dei buoni programmatori.

Non ne sono così sicuro - forse l'aumento della potenza di calcolo significa che non dobbiamo più considerare questo tipo di miglioramenti delle micro-prestazioni? Forse questo tipo di considerazione spetta alle persone che scrivono il codice della lingua attuale? (di PHP nel caso precedente).

I fattori ambientali potrebbero essere importanti: Internet consuma il 10% dell'energia mondiale. Mi chiedo quanto siano sprecati pochi microsecondi di codice quando vengono replicati migliaia di miliardi di volte su milioni di siti web?

Mi piacerebbe conoscere le risposte preferibilmente sulla base di fatti sulla programmazione.

La micro-ottimizzazione è importante per la codifica?

Il mio riassunto personale di 25 risposte, grazie a tutti.

A volte dobbiamo davvero preoccuparci delle micro-ottimizzazioni, ma solo in circostanze molto rare. Affidabilità e leggibilità sono molto più importanti nella maggior parte dei casi. Tuttavia, considerando la micro-ottimizzazione di tanto in tanto, non fa male. Una comprensione di base può aiutarci a non rendere evidenti le cattive scelte quando codifica come

if (expensiveFunction() || counter < X)

Dovrebbe essere

if (counter < X || expensiveFunction())

( Esempio da @ zidarsk8 ) Questa potrebbe essere una funzione poco costosa e pertanto la modifica del codice sarebbe micro- ottimizzazione. Ma con una comprensione di base, non dovresti farlo, perché in primo luogo dovresti scriverlo correttamente.

    
posta Boz 23.05.2017 - 14:40
fonte

32 risposte

0

Esistono micro-ottimizzazioni e micro-ottimizzazioni. In VB (sia VB6 che VB.NET, ma ignorando l'offerta IsNullOrEmpty dal framework) utilizzo sempre Len(str) <> 0 piuttosto che str <> "" . Tuttavia, di solito non "aggiusto" il codice degli altri in cui hanno usato quest'ultimo.

Sì, quest'ultimo è più leggibile, ma, in questo caso, il primo non è illeggibile.

Le prestazioni dovrebbero essere una considerazione quando si progetta il codice, ma non al diminuire della leggibilità e della manutenibilità.

    
risposta data 20.06.2012 - 10:00
fonte
0

Ho iniziato a programmare quasi 31 anni fa, dove la memoria e la CPU sono scarse. Forse è per questo che sono d'accordo con tuo padre.

Credo che un buon programmatore debba preoccuparsi dell'ottimizzazione in ogni riga di codice. Ma vorrei aggiungere a questa frase: per quanto ne vale e sempre cercando di favorire la leggibilità rispetto all'ottimizzazione nei luoghi in cui i calcoli non sono critici .

Ad esempio, in un altro thread, un tizio ha chiesto del codice seguente, quale soluzione avrebbe scelto: CPU o memoria.

public class Main {

    public static int totalRevenue;
    public static int totalProfit;

    public static int option1(int numSold, int price, int cost) {
        // Option 1 (memory)
        totalRevenue += numSold * price;
        totalProfit += numSold * price - numSold * cost;
        return numSold * price;
    }

    public static int option2(int numSold, int price, int cost) {
        // Option 2 (time)
        int saleRevenue = numSold * price;
        totalRevenue += saleRevenue;
        totalProfit += saleRevenue - numSold * cost;
        return saleRevenue;
    }
}

Questo codice genera il seguente codice byte:

public class Main {
  public static int totalRevenue;

  public static int totalProfit;

  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static int option1(int, int, int);
    Code:
       0: getstatic     #2                  // Field totalRevenue:I
       3: iload_0
       4: iload_1
       5: imul
       6: iadd
       7: putstatic     #2                  // Field totalRevenue:I
      10: getstatic     #3                  // Field totalProfit:I
      13: iload_0
      14: iload_1
      15: imul
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_0
      25: iload_1
      26: imul
      27: ireturn

  public static int option2(int, int, int);
    Code:
       0: iload_0
       1: iload_1
       2: imul
       3: istore_3
       4: getstatic     #2                  // Field totalRevenue:I
       7: iload_3
       8: iadd
       9: putstatic     #2                  // Field totalRevenue:I
      12: getstatic     #3                  // Field totalProfit:I
      15: iload_3
      16: iload_0
      17: iload_2
      18: imul
      19: isub
      20: iadd
      21: putstatic     #3                  // Field totalProfit:I
      24: iload_3
      25: ireturn
}

A fini di comprensibilità, "iload_" carica i dati dallo stack e "istore_" salva i dati nello stack.

È facile notare che hai davvero salvato un'allocazione di memoria in una soluzione spendendo più cicli della CPU. Questo tipo di domande possono sorgere anche per i programmatori esperti.

Ma c'è un problema in questo esempio: la memoria dello stack è pre-allocata in blocchi, non a livello di byte. Ogni volta che viene eseguito un thread, verrà allocata una certa quantità di memoria da utilizzare nelle operazioni di stack. Quindi, a meno che tu non abbia la fortuna di avere questi 4 byte in overflow per il tuo stack (e richiedendo di impostare una dimensione di stack più grande), finirai per spendere la stessa quantità di memoria per eseguire entrambi gli esempi. Ma nella seconda, stai spendendo più cicli facendo calcoli matematici e il tuo codice è molto meno leggibile.

L'ho portato qui per dare un esempio che discutere di ottimizzazioni in piccole porzioni di codice non è malvagio. Qualche ragazzo ha chiuso quella domanda puntando su questo thread. Ma questa discussione non risponde a quella domanda specifica. Parla solo di "non preoccuparti dell'ottimizzazione". E a causa di questo stupido mantra, le persone sentono che non è giusto andare in profonda comprensione.

C'è una risposta ragionevole a questa domanda, e forse si può anche dare una risposta migliore riguardo gli interni. Una volta appreso, un buon programmatore sarà in grado di ripetere istintivamente quel modello e diventerà un programmatore migliore. I programmatori devono avere un pensiero critico sul loro codice e devono cercare di capire, per quanto possibile, come lo elaborerà la macchina.

Non sto sostenendo qui che abbiamo tutti bisogno di ottimizzare piccole cose. Ricorda che ho raccomandato di privilegiare la leggibilità rispetto alle micro-ottimizzazioni.

Credo solo che ripetere il mantra "non preoccuparti dell'ottimizzazione" non migliori le cose. Rende pigri solo i programmatori. I programmatori devono essere istigati a sapere come funzionano le cose dietro le quinte. In questo modo le persone possono continuare a scrivere codice migliore e scegliere saggiamente quando non ottimizzare .

    
risposta data 17.11.2015 - 22:17
fonte

Leggi altre domande sui tag