Domanda

Quando devi avere oggetti molto piccoli, supponi che contenga 2 proprietà float e ne avrai milioni che non verranno "distrutti". subito, le strutture sono una scelta o classi migliori?

Come in xna come libreria, ci sono point3s, ecc. come strutture ma se è necessario mantenere questi valori per molto tempo, costituirebbe una minaccia alle prestazioni?

È stato utile?

Soluzione

Contrariamente alla maggior parte delle domande sulle strutture, questo in realtà sembra essere un buon uso di una struttura. Se i dati che contiene sono tipi di valore e ne utilizzerai molti, una struttura funzionerebbe bene.

Alcuni consigli:

:: La struttura non deve essere maggiore di 16 byte, altrimenti si perdono i vantaggi in termini di prestazioni.

:: Rendi immutabile la struttura. Ciò rende l'utilizzo più chiaro.

Esempio:

public struct Point3D {

   public float X { get; private set; }
   public float Y { get; private set; }
   public float Z { get; private set; }

   public Point3D(float x, float y, float z) {
      X = x;
      Y = y;
      Z = z;
   }

   public Point3D Invert() {
      return new Point3D(-X, -Y, -Z);
   }

}

Altri suggerimenti

La risposta dipende da dove verranno archiviati gli oggetti / i valori. Se devono essere archiviati in una raccolta non tipizzata come ArrayList, finisci per inscatolarli. La boxe crea un wrapper di oggetti per una struttura e l'impronta è la stessa di un oggetto di classe. D'altra parte, se si utilizza un array tipizzato come T [] o List, l'utilizzo delle strutture memorizzerà solo i dati effettivi per ciascun elemento con footprint per l'intera raccolta e non i suoi elementi.

Quindi le strutture sono più efficienti per l'uso negli array T [].

La grande preoccupazione è se la memoria è allocata nello stack o nell'heap. Le strutture vanno nello stack per impostazione predefinita e lo stack è generalmente molto più limitato in termini di spazio. Quindi creare un sacco di strutture come questa può essere un problema.

In pratica, tuttavia, non penso che sia un grosso problema. Se ne hai molti, probabilmente fanno parte di un'istanza di classe (sull'heap) da qualche parte.

Struct sembra giusto per questa applicazione.

Tieni presente che il "quot" deve trattenere quei valori S " implica la loro memorizzazione sull'heap da qualche parte, probabilmente un campo array di un'istanza di classe.

Una cosa a cui fare attenzione è che ciò si traduce in un'allocazione sull'heap di oggetti di grandi dimensioni. Non è così chiaro come, se non del tutto, questo mucchio si deframmenta da solo, tuttavia per oggetti di lunga durata che forse non è un problema.

L'uso della classe per milioni di questi tipi di dati sarebbe probabilmente costoso nel volume di dereferenziazione che probabilmente avrà luogo per operazioni su questo tipo.

Di norma, le matrici di grandi dimensioni di dati non alias (cioè non condivisi) dello stesso tipo vengono archiviate al meglio in strutture per prestazioni poiché si riduce il numero di indiretti. (Vedi anche when-are-structs-the-answer ). L'esatta differenza di prestazioni tra classe e struttura dipende dall'utilizzo. (Ad esempio, nelle operazioni accedete solo a parti della struttura? Effettuate molte copie temporanee? Se la struttura è piccola è probabilmente sempre meglio usarla ma se è grande, la creazione di copie temporanee potrebbe rallentare. Se per renderlo immutabile dovrai sempre copiare tutto per cambiare il valore.)

In caso di dubbi, misurare.

Dato che sei interessato a possibili effetti a lungo termine che potrebbero non essere evidenti da tale misurazione, tieni presente che tali array sono probabilmente memorizzati nell'heap di oggetti di grandi dimensioni e devono essere riutilizzati anziché distrutti e riassegnati . (vedi CRL Inside Out: grande mucchio di oggetti scoperto .)

Quando si passano strutture di dimensioni maggiori nelle chiamate, è possibile passarle con l'argomento ref per evitare la copia.

I tipi di valore (struct) sono validi per tipi che non sono allocati spesso sull'heap, ovvero sono per lo più contenuti in un altro riferimento o tipo di valore.

L'esempio di Vector3 che hai fornito è un esempio perfetto. Raramente Vector3 ciondolerà nell'heap, il più delle volte sarà contenuto in un tipo che è esso stesso nell'heap o utilizzato come variabile locale, nel qual caso verrà allocato nello stack.

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