2014-06-27 13 views
10

Dati i seguenti struct:Go - Prestazioni - Qual è la differenza tra puntatore e valore in struct?

type Exp struct { 
    foo int, 
    bar *int 
} 

Qual è la differenza in termini di prestazioni quando si utilizza un puntatore o un valore in una struttura. C'è qualche sovraccarico o solo due scuole di programmazione Go?

Vorrei utilizzare i puntatori per implementare una struttura concatenata ma è questo l'unico caso in cui dobbiamo utilizzare i puntatori nella struttura per ottenere prestazioni?

PS: nella struct sopra si parla di un semplice int ma potrebbe essere qualsiasi altro tipo (anche su misura uno)

risposta

21

Utilizzare il modulo che è più utile dal punto di vista funzionale per il programma. Fondamentalmente, questo significa che è utile che il valore sia nil, quindi utilizzare un puntatore.

Dal punto di vista delle prestazioni, i tipi numerici primitivi sono sempre più efficienti da copiare rispetto al dereferenziamento di un puntatore. Anche le strutture di dati più complesse sono ancora più veloci da copiare se sono più piccole di una linea cache o due (sotto 128 byte è una buona regola per le CPU x86).

Quando le cose diventano un po 'più grandi, è necessario fare un benchmark se le prestazioni riguardano te. Le CPU sono molto efficienti per la copia dei dati, e ci sono così tante variabili coinvolte che determinano la località e la cache dei tuoi dati, dipende molto dal comportamento del tuo programma e dall'hardware che stai utilizzando.

Questa è un'eccellente serie di articoli se si desidera comprendere meglio il modo in cui la memoria e il software interagiscono: "What every programmer should know about memory".

In breve, dico alle persone di scegliere un puntatore o meno in base alla logica del programma e preoccuparsi delle prestazioni in seguito.

  • Utilizzare un puntatore se è necessario passare qualcosa da modificare.
  • Utilizzare un puntatore se è necessario determinare se qualcosa è stato disattivato/nullo.
  • Utilizzare un puntatore se si utilizza un tipo con metodi con destinatari del puntatore.
+1

Aggiungo solo un chiarimento alla tua risposta eccellente: manca il quarto punto: "altrimenti, non usare un puntatore a meno che non dia un miglioramento delle prestazioni molto chiaro" –

1

Se la dimensione di un puntatore è inferiore al membro struct, quindi utilizzando un puntatore è più efficiente dal momento che non è necessario copiare il membro ma solo il suo indirizzo. Inoltre, se vuoi essere in grado di spostare o condividere parte di una struttura, è meglio avere un puntatore in modo che tu possa, di nuovo, solo condividere l'indirizzo del membro. Vedi anche lo golang faqs.

+1

Thx per la risposta. Quando parli della copia "l'uso di un puntatore è più efficiente dal momento che non hai bisogno di copiare il membro ma solo il suo indirizzo", è anche questo anche se utilizziamo solo Exp come puntatore, ad es. * Exp? Inoltre, se definiamo un metodo sul tipo Exp e non su * Exp, ciò che stai dicendo sulle copie si applica ogni volta che chiamiamo quel metodo, cioè c'è una copia di Exp il metodo viene chiamato? (Penso di sì dopo aver letto il frocetto sulla definizione del metodo). – fsenart

+1

Sì, un argomento di tipo 'Exp' verrà copiato ogni volta. E sì, se hai un argomento 'Exp *' il membro non verrà copiato. I puntatori consentono di condividere dati e di trasferire in modo compatto i dati. – perreal

+3

L'utilizzo di un puntatore può essere più efficiente * in memoria *, ma probabilmente peggiorerà in molti casi perché si perde la località dei dati. Se i dati appartengono insieme e si accede frequentemente insieme, quindi tenerli insieme. – zmb

Problemi correlati