Pregunta

Cuando necesites tener objetos muy pequeños, digamos que contiene 2 propiedades flotantes, y tendrás millones de ellos que no serán " destruidos " De inmediato, ¿son las estructuras una mejor elección o clases?

Al igual que en xna como una biblioteca, hay point3s, etc. como estructuras, pero si necesita mantener esos valores durante mucho tiempo, ¿representaría una amenaza para el rendimiento?

¿Fue útil?

Solución

Al contrario de la mayoría de las preguntas sobre estructuras, esto en realidad parece ser un buen uso de una estructura. Si los datos que contiene son tipos de valor, y va a utilizar muchos de estos, una estructura funcionaría bien.

Algunos consejos:

:: La estructura no debe tener más de 16 bytes, o perderá las ventajas de rendimiento.

:: Haz que la estructura sea inmutable. Eso hace que el uso sea más claro.

Ejemplo:

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);
   }

}

Otros consejos

La respuesta depende de dónde se almacenarán finalmente los objetos / valores. Si se van a almacenar en una colección sin tipo como ArrayList, entonces terminas boxeando. El boxeo crea una envoltura de objeto para una estructura y la huella es la misma que con un objeto de clase. Por otro lado, si usa una matriz con tipo como T [] o Lista, entonces el uso de estructuras solo almacenará los datos reales de cada elemento con huella solo para toda la colección y no sus elementos.

Por lo tanto, las estructuras son más eficientes para su uso en matrices T [].

La gran preocupación es si la memoria está asignada en la pila o en el montón. Las estructuras van en la pila por defecto, y la pila es generalmente mucho más limitada en términos de espacio. Por lo tanto, crear un montón de estructuras así puede ser un problema.

En la práctica, sin embargo, realmente no creo que sea un gran problema. Si tienes muchos de ellos, es probable que formen parte de una instancia de clase (en el montón) en algún lugar.

Struct parece correcto para esta aplicación.

Tenga en cuenta que la " necesidad de mantener esos valoresS " implica su almacenamiento en el montón en algún lugar, probablemente un campo de matriz de una instancia de clase.

Una cosa a tener en cuenta es que esto se traduce en una asignación en el montón de objetos grandes. No está tan claro cómo, si es que lo hace, este montón se desfragona a sí mismo, sin embargo, para los objetos de vida muy larga eso quizás no sea un problema.

El uso de la clase para millones de estos tipos de datos probablemente sea costoso en el volumen de referencia de la anulación de la referencia que probablemente se llevará a cabo para las operaciones en este tipo.

Como regla general, las matrices grandes de datos sin alias (es decir, no compartidos) del mismo tipo se almacenan mejor en estructuras para el rendimiento, ya que se reduce el número de indirectas. (Consulte también when-are-structs-the-answer ). La diferencia exacta de rendimiento entre clase y estructura depende de su uso. (Por ejemplo, en operaciones, ¿solo accede a partes de la estructura? ¿Hace una gran cantidad de copias temporales? Si la estructura es pequeña, es probable que siempre sea mejor usarla, pero si es grande, la creación de copias temporales puede ralentizarle. para que sea inmutable, siempre tendrá que copiar todo para cambiar el valor.)

En caso de duda, mida.

Debido a que está interesado en posibles efectos a largo plazo que pueden no ser evidentes por tal medida, tenga en cuenta que tales arreglos probablemente se almacenen en el montón de objetos grandes y se deben reutilizar en lugar de destruir y volver a asignar. . (consulte CRL Inside Out: montón de objetos grandes al descubierto .)

Al pasar estructuras de mayor tamaño en llamadas, es posible que desee pasarlas con el argumento ref para evitar copiarlas.

Los tipos de valor (struct) son buenos para los tipos que no se asignan en el montón a menudo, es decir, se encuentran principalmente en otra referencia o tipo de valor.

El ejemplo de Vector3 que diste es un ejemplo perfecto. Rara vez tendrá Vector3 colgado en el montón, la mayoría de las veces estará contenido en un tipo que está en el montón, o se usará como una variable local, en cuyo caso, se asignará en la pila.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top