Domanda

MSDN afferma che una classe di 16 byte o meno verrebbe gestita meglio come struttura [citazione].
Perché?
Ciò significa che se una struttura supera i 16 byte è meno efficiente di una classe o è la stessa cosa?
Come determini se la tua classe ha meno di 16 byte?
Cosa impedisce a una struttura di agire come una classe?(oltre a non consentire costruttori senza parametri)

È stato utile?

Soluzione

Ci sono un paio di risposte diverse a questa domanda, ed è un po 'soggettivo, ma alcune ragioni mi vengono in mente sono:

  • Structs sono value-type, classi sono tipo di riferimento. Se si utilizza 16 byte per l'archiviazione totale, probabilmente non vale la pena di creare riferimenti di memoria (da 4 a 8 byte) per ciascuno di essi.
  • Quando si ha realmente piccoli oggetti, che spesso può essere inserito nello stack IL, invece di riferimenti agli oggetti. Questo può davvero accelerare il codice, come si sta eliminando un dereference di memoria sul lato chiamato.
  • C'è un po 'di "fluff" in più associato con le classi in IL, e se la vostra struttura dei dati è molto piccolo, niente di tutto questo fluff sarebbe stato utilizzato in ogni caso, quindi è solo spazzatura in più non è necessario.

La differenza principale tra una struttura e una classe, però, è che le strutture sono di tipo valore e le classi sono tipo di riferimento.

Altri suggerimenti

Con il termine "efficace", sono probabilmente parlando della quantità di memoria che serve per rappresentare la classe o struct.

Sulla piattaforma 32-bit, assegnando un oggetto richiede un minimo di 16 byte. Su una piattaforma a 64-bit, la dimensione minima dell'oggetto è di 24 byte. Quindi, se stai guardando puramente dalla quantità di memoria utilizzata, una struttura che contiene meno di 16 byte di dati sarà "migliore" rispetto alla classe corrispondente.

Ma la quantità di memoria utilizzata non è tutta la storia. tipi di valore (struct) sono fondamentalmente diverso tipi di riferimento (classi). Le strutture può essere scomodo con cui lavorare, e può effettivamente causare problemi di prestazioni se non stai attento.

La vera risposta, naturalmente, è quello di utilizzare a seconda di quale funziona meglio nella vostra situazione. Nella maggior parte dei casi, sarete molto meglio utilizzare le classi.

Controlla questo collegamento, l'ho trovato su una delle risposte in SO oggi: Interni di tipo .NET.Puoi anche provare a cercare SO e Google su "tipi di riferimento e tipi di valore" per le differenze tra strutture e classi.

Cosa impedisce a una struttura di agire come una classe?

Ci sono molte differenze.Non è possibile ereditare da una struttura, ad esempio.

Non è possibile avere metodi virtuali, quindi non è possibile utilizzare una struttura per implementare un'interfaccia.I metodi di istanza nelle strutture possono accedere ai campi privati ​​della struttura, ma a parte questo si comportano in modo molto simile alle funzioni "helper" ausiliarie (per le strutture immutabili, a volte non hanno nemmeno bisogno di accedere ai dati privati).Quindi trovo che non siano così "preziosi" come i metodi di classe.

Ciò è dovuto al diverso modo in cui il CLR gestisce le strutture e le classi. Le strutture sono tipi di valore che significa che vivono sullo stack piuttosto che nel mucchio gestito. E 'una buona regola per mantenere le strutture piccole, perché una volta che si avvia passandoli come argomenti di metodo si dovranno sostenere spese generali come le strutture sono copiati nella loro interezza quando viene passato a un metodo.

Poiché classi passano una copia del loro riferimento a metodi sostenute molto meno overhead quando usato come argomenti di metodo.

Il modo migliore per determinare la dimensione della classe è a totale il numero di byte necessari da parte di tutti i membri della tua classe, più un extra di 8 byte per roba in testa CLR (l'indice di blocco di sincronizzazione e il riferimento al tipo di oggetto).

Structs sono diverse dalle classi, perché sono memorizzati sullo stack, e non sul mucchio. Ciò significa che ogni volta che si chiama un metodo con lo struct come parametro, una copia viene creata e passata al metodo. Ecco perché grandi sono le strutture estremamente inefficiente.

Vorrei attivamente scoraggiare ad utilizzare le strutture, tuttavia, perché potrebbe causare alcuni bug sottili: ad esempio, quando si cambia un campo di una struttura, la sua non intenzione di essere riflessa per il chiamante (perché è stata modificata solo la copia) -., che è un comportamento completamente diverso per le classi

Così i 16 byte credo sia una dimensione massima ragionevole di una struttura, ma ancora nella maggior parte dei casi è meglio avere una classe. Se si desidera comunque creare una struttura, cercare di renderlo immutabile almeno.

In memoria, lo struct terrà i dati direttamente, mentre una classe si comporterà più come un puntatore. Solo questo fa una differenza importante, poiché passando struct come parametro a un metodo passerà suoi valori (li copia nello stack), mentre la classe passerà il riferimento ai valori. Se la struct è grande, vi sarà la copia di un sacco di valori su ogni chiamata di metodo. Quando è davvero piccolo copiare i valori e li utilizzano direttamente sarà probabilmente più veloce rispetto alla copia del puntatore e di dover prendere loro da un altro luogo.

A proposito di restrizioni:. Non è possibile assegnare a NULL (anche se è possibile utilizzare Nullable <>) e si deve inizializzare subito

Copia di un'istanza di una struct richiede meno tempo rispetto alla creazione di una nuova istanza di una classe di dati e la copia di un vecchio, ma le istanze di classe possono essere condivisi e le istanze struct non può. Così, "structvar1 = structvar2" richiede copia nuova istanza struct, mentre "classvar1 = classvar2" consente classvar1 e classvar2 riferiscono alla stessa istanza struct (senza dover creare uno nuovo).

Il codice per gestire la creazione di nuovi casi struct è ottimizzato per dimensioni fino a 16 byte. le strutture più grandi sono gestite in modo meno efficiente. Le strutture sono una vittoria nei casi in cui ogni variabile che contiene una struct terrà un'istanza indipendente (cioè non c'è ragione di aspettarsi che qualsiasi particolare due variabili terranno istanze identiche); non sono molto di una vittoria (se sono una vittoria a tutti) nei casi in cui molte variabili potrebbero tenere la stessa istanza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top