with property net microsoft example define c# oop properties struct public-fields

c# - property - ¿Por qué los campos públicos son más rápidos que las propiedades?



struct c# (5)

Estuve hurgando en XNA y vi que la clase Vector3 estaba usando campos públicos en lugar de propiedades. Probé un punto de referencia rápido y descubrí que, para una struct la diferencia es bastante dramática (al agregar dos vectores juntos, 100 millones de veces tomaron 2.0 con propiedades y 1.4 con campos). Para un tipo de referencia, la diferencia no parece ser tan grande, pero está allí.

Entonces, ¿por qué es eso? Sé que una propiedad se compila en los métodos get_X y set_X , que incurriría en una sobrecarga de llamada a un método. Sin embargo, ¿estos getters / setters simples siempre se alinean con el JIT? Sé que no se puede garantizar lo que el JIT decide hacer, pero seguramente esto es bastante alto en la lista de probabilidades. ¿Qué más hay que separa un campo público de una propiedad en el nivel de la máquina?

Y una cosa que me he estado preguntando: ¿cómo es una propiedad implementada automáticamente ( public int Foo { get; set; } ) ''mejor'' OO-design que un campo público? O mejor dicho: ¿cómo son esos dos diferentes ? Sé que convertirlo en una propiedad es más fácil con la reflexión, pero ¿algo más? Apuesto a que la respuesta a ambas preguntas es la misma.

Por cierto: estoy usando .NET 3.5 SP1 que creo corrigió problemas donde los métodos con estructuras (o métodos de estructuras, no estoy seguro) no estaban alineados, así que no es así. Creo que lo estoy usando al menos, está ciertamente instalado, pero de nuevo, estoy usando Vista de 64 bits con SP1, que debería tener DX10.1, excepto que no tengo DX10.1.

Además: sí, he estado ejecutando una versión de lanzamiento :)

EDITAR : Aprecio las respuestas rápidas chicos, pero indiqué que sé que el acceso a una propiedad es una llamada a un método, pero que no sé por qué, presumiblemente, el método alineado es más lento que el acceso directo al campo.

EDIT 2 : Así que creé otra struct que usaba métodos GetX () explícitos (o cómo no echo de menos mis días de Java) y que realizaba lo mismo si deshabilitaba el forro interno (a través de [MethodImplAttribute(MethodImplOptions.NoInlining)] ) o no, así que conclusión: los métodos no estáticos aparentemente nunca están en línea, ni siquiera en las estructuras.

Pensé que había excepciones, donde el JIT podría optimizar la llamada al método virtual. ¿Por qué no puede suceder esto en estructuras que no conocen herencia y, por lo tanto, una llamada a un método solo puede apuntar a un posible método, ¿no? ¿O es porque puedes implementar una interfaz en él?

Es una lástima, ya que realmente me hará pensar en el uso de propiedades críticas para el rendimiento, pero el uso de campos me hace sentir sucio y también podría escribir lo que estoy haciendo en C.

EDIT 3 : Encontré this publicación sobre el mismo tema. Su conclusión final es que la llamada a la propiedad se optimizó. También podría haber jurado que he leído muchas veces que las propiedades simples de getter / setter se callvirt , a pesar de ser callvirt en IL. Entonces, ¿me estoy volviendo loco?

EDIT 4 : Reed Copsey publicó la respuesta en un comentario a continuación:

Re: Edit3 - vea mi comentario actualizado: Creo que esto es x86 JIT vs x64 JIT emite. el JIT en x64 no es tan maduro. Espero que MS mejore esto rápidamente a medida que más sistemas de 64 bits entren en línea todos los días. - Reed Copsey

Y mi respuesta a su respuesta:

Gracias, esta es la respuesta! Intenté forzar una compilación x86 y todos los métodos son igualmente rápidos y mucho más rápidos que el x64. Esto es realmente impactante para mí, no tenía idea de que vivía en la edad de piedra en mi sistema operativo de 64 bits. Incluiré su comentario en mi respuesta para que se destaque mejor. - JulianR

¡Gracias a todos!



Editar 2:

Tenía otro pensamiento potencial aquí:

Mencionaste que estás ejecutando x64. He probado este mismo problema en x86 y he visto el mismo rendimiento cuando uso propiedades automáticas frente a campos. Sin embargo, si observa las publicaciones de Connect y de la lista de correo / foro, hay muchas referencias en línea sobre el hecho de que el JIT de x64 CLR es una base de código diferente y tiene características de rendimiento muy diferentes al x86 JIT. Creo que este es un lugar donde x64 todavía está rezagado.

Además, para su información, la cosa struct / method / etc arreglada en .net 3.5sp1 estaba en el lado x86, y era el hecho de que las llamadas a métodos que tomaban estructuras como un parámetro nunca serían inlineadas en x86 antes de .net3.5sp1. Eso es bastante irrelevante para esta discusión en su sistema.

Editar 3:

Otra cosa: sobre por qué XNA está usando campos. De hecho, estaba en el Game Fest donde anunciaron XNA. Rico Mariani dio una charla donde mencionó muchos de los mismos puntos que están en su blog. Parece que los amigos de XNA tenían ideas similares cuando desarrollaron algunos de los objetos centrales. Ver:

http://blogs.msdn.com/ricom/archive/2006/09/07/745085.aspx

Particularmente, mira el punto n. ° 2.

En cuanto a por qué las propiedades automáticas son mejores que los campos públicos:

Le permiten cambiar la implementación en v2 de su clase y agregar lógica a las rutinas get / set de la propiedad según sea necesario, sin cambiar su interfaz a sus usuarios finales. Esto puede tener un efecto profundo en su capacidad para mantener su biblioteca y código a lo largo del tiempo.

---- De la publicación original, pero descubrió que este no era el problema --------

¿Estabas ejecutando una versión de lanzamiento fuera de VS? Esa puede ser una explicación de por qué las cosas no están siendo optimizadas. A menudo, si está ejecutando en VS, incluso una compilación de versión optimizada, el proceso de host VS deshabilita muchas funciones del JIT. Esto puede hacer que los puntos de referencia de rendimiento cambien.


El acceso a un campo es solo una referencia de memoria, mientras que usar una propiedad en realidad está invocando un método e incluye la sobrecarga de llamada de función. La razón para usar propiedades en lugar de campos es aislar su código de los cambios y proporcionar una mayor granularidad sobre el acceso. Al no exponer directamente su campo, tiene un mayor control sobre cómo se realiza el acceso. El uso de campos automáticos le permite obtener el típico comportamiento getter / setter, pero desarrolla la capacidad de cambiar esto sin una necesidad posterior de que los cambios se propaguen a otras partes del código.

Por ejemplo, supongamos que quiere cambiar su código para que el acceso al campo esté controlado por el rol del usuario actual. Si hubiera expuesto el campo públicamente, tendría que tocar cada parte del código que lo accedió. Exponerlo a través de una propiedad le permite modificar el código de propiedad para agregar su nuevo requisito, pero no da como resultado cambios innecesarios a ningún código que acceda a él .


XNA tiene que dirigirse a XBox 360, y el JIT en .NET Compact Framework no es tan sofisticado como su contraparte de escritorio. El .NET CF JIT''er no alineará los métodos de propiedad.


  • Los campos públicos son asignaciones directas
  • Las propiedades son métodos, luego más código, insignificante pero más.