2012-02-12 8 views
6

Actualmente estoy leyendo de Oreilly Learning XNA 4.0 y me he dado cuenta de que el autor es propenso a la creación de un valor de estructura, tales como Vector2 o Rectangle varias veces sin tener en cuenta el rendimiento.Rendimiento de crear estructura valora

Por ejemplo, un método SquareCollision(), que comprueba la colisión entre dos entidades juego crea dos Rectangle s cada vez que se llama, en lugar de simplemente tener cada entidad juego sostener su propio campo Rectangle y comparar los campos sin crear más struct valores.

He visto este patrón muchas veces en muchos lugares y eso me hizo preguntarme:
¿La creación de valores de estructura es despreciable en C#?
¿Esto realmente cae bajo la sección de micro-optimizaciones?

Tal vez porque mi experiencia es en su mayoría con Java, el concepto de ValueType s es extraño para mí, pero parece que la recreación de un valor de una estructura (y llamar a su constructor) varias veces parece como una gran pérdida de recursos.

+2

¿Has intentado perfilarlo? –

+0

Creo que esto es un poco difícil de perfilar, porque lo que realmente importa es el rendimiento general. Incluso si la recreación del mismo valor es 10.000 veces más lenta que utilizando un campo, todavía significaría poco si solo tiene un impacto de 0,0001% en el rendimiento. (Perdón por los números arbitrarios, solo intento asegurarme de que me comprendan.) Lo que trato de entender es cuán mala práctica es en realidad (si es que la hay) y si debo o no tratar de evitar hacerlo. – Acidic

+1

Puede hacer que la pregunta sea un poco más concreta al mostrar el código. Evita malentendidos. –

Respuesta

6

Crear una estructura para un uso breve en la pila es muy barato, y no es muy diferente a simplemente establecer variables locales para todos esos valores, pero con la componente. Sin embargo, como parte del objeto, sería un duplicado adicional de los mismos datos por objeto.

Ambos enfoques son válidos, dependiendo de la situación. En la pila, sin embargo, no hay un costo real de recursos. Como parte de un objeto, querría asegurarse de que no estaba duplicando datos innecesariamente, ya que eso tendría un costo real.

Si fuera una propiedad de un objeto, tendría que copiarlo muchas veces.

Si se tratara de un campo en un objeto, sí: se podría usar in situ sin haberlo copiado nunca, pero esto es relativamente pequeño en la mayoría de los casos.

Como siempre, necesitaría un perfil para saber si importaba.

+0

Me parece que la única forma de salir de esto es utilizar ** campos ** protegidos/públicos para asegurarse de que se usa la misma estructura todo el tiempo, en lugar de duplicarla innecesariamente. ¿O tal vez un método que recibe estructuras por referencia usando la palabra clave 'ref'? – Acidic

+0

@Acidic si usa la estructura ** directamente ** (no asignando una variable, etc.), entonces no necesita una copia; pero sí, los métodos que toman estructuras a través de "ref" son bastante comunes en este escenario. Yo uso ese enfoque yo mismo en algunos lugares locos optimizados. –

1

Lo que tiene esa estructura dentro de su (digamos) objeto Mesh no le beneficiará, básicamente. Causa en el momento de la solicitud, el valor de la estructura será copiado. Considere ejemplo:

public class Mesh 
{ 
    public Vector3 MeshCogVector {get;set}; 
} 

y en alguna parte del código que tienen

public void CollisionDetection 
{ 
    for(int i=0;....) 
    { 
     Mesh curmesh = listofmashes[i]; 
     Vector3 vec3 = curmesh.MeshCogVector; //value copied 

    } 
} 

Así, utilizando de esta manera en sus condiciones, que, básicamente, no recibe ningún beneficio + a aumentar su tamaño Mesh ejemplo.

En lugar de usar/construir esa instancia Vector3 dentro del método real, en el momento en que realmente lo necesita, obtiene rápidamente la asignación de la pila y la recolección rápida de la basura.

Si no está satisfecho con un rendimiento en estructuras, puede considerar el uso de matrices de datos non safe. Pero esto es algo que debe medir, para comprender si este es un escenario adecuado para usted.

+0

¿no se resolvería esto si simplemente utilizo un campo público en lugar de una propiedad pública? Según lo entiendo, struct properties crea una nueva copia de la estructura en la llamada getter. – Acidic

+0

@Acidic: no, no cambiaría nada. No se trata de un parámetro de retorno propiedad/campo/función de acceso, se trata de [tipos de valores C#] (http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx). Puede ** intentar **, si desea mantener un 'Vector' dentro de la clase, pasarlo con la palabra clave' ref' las funciones como 'CollisionDetection'. En este caso, el valor no se copiará, sino que se pasará ** por referencia **. Pero es algo, una vez más, que tienes que medir. Me gustaría ir, si la clase 'Vector' no es grande, para la solución que ya ha visto, por lo que la asignación en el momento cuando sea necesario. – Tigran

+0

Odio hacer tales preguntas, pero ¿qué es * grande *? Un 'Vector2' podría no ser grande, pero ¿qué pasa con' Vector4' o 'Rectangle'? Supongo que * esto * solo se puede responder con un perfil ... – Acidic

Cuestiones relacionadas