Tenga en cuenta que esta pregunta está relacionada únicamente con el rendimiento. Vamos a omitir las pautas de diseño, la filosofía, la compatibilidad, la portabilidad y todo lo que no esté relacionado con el rendimiento puro. Gracias.Campo vs Propiedad. Optimización del rendimiento
Ahora a la pregunta. Siempre asumí que debido a que C# getters/setters son realmente métodos disfrazados, entonces leer el campo público debe ser más rápido que llamar a un getter.
Para asegurarse de que hice una prueba (el código a continuación). Sin embargo, esta prueba solo produce los resultados esperados (es decir, los campos son más rápidos que getters al 34%) si lo ejecuta desde Visual Studio.
Una vez que se ejecuta desde la línea de comandos se muestra más o menos el mismo tiempo ...
La única explicación podría ser es que el CLR hace una optimización adicional (corrígeme si estoy equivocado aquí).
No creo que en una aplicación real donde esas propiedades se usen de una manera mucho más sofisticada se optimicen de la misma manera.
Por favor, ayúdame a demostrar o refutar la idea de que en las propiedades de la vida real son más lentos que los campos.
La pregunta es: ¿cómo debo modificar las clases de prueba para hacer que el CLR cambie el comportamiento para que el campo público supere a los getters? O muéstreme que cualquier propiedad sin lógica interna funcionará igual que un campo (al menos en el captador)
EDITAR: Estoy hablando solamente de la versión de lanzamiento x64.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PropertyVsField
{
class Program
{
static int LEN = 20000000;
static void Main(string[] args)
{
List<A> a = new List<A>(LEN);
List<B> b = new List<B>(LEN);
Random r = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < LEN; i++)
{
double p = r.NextDouble();
a.Add(new A() { P = p });
b.Add(new B() { P = p });
}
Stopwatch sw = new Stopwatch();
double d = 0.0;
sw.Restart();
for (int i = 0; i < LEN; i++)
{
d += a[i].P;
}
sw.Stop();
Console.WriteLine("auto getter. {0}. {1}.", sw.ElapsedTicks, d);
sw.Restart();
for (int i = 0; i < LEN; i++)
{
d += b[i].P;
}
sw.Stop();
Console.WriteLine(" field. {0}. {1}.", sw.ElapsedTicks, d);
Console.ReadLine();
}
}
class A
{
public double P { get; set; }
}
class B
{
public double P;
}
}
Bobb, Microsoft sabe muy bien que por mucho que pregonen la filosofía/filosofía del diseño, todos usarían campos públicos en lugar de propiedades una vez que se den cuenta de que es un 34% más rápido (aunque es una micro optimización en el 99,9% de los casos, la gente lo haría de todos modos). Así que Eric Lipperts del mundo ha creado un compilador y optimizador muy bueno que se da cuenta de que su propiedad automática es un campo público disfrazado y lo optimiza en consecuencia. – dasblinkenlight
Es posible que desee intentar hacer B una estructura en lugar de una clase si está utilizando solo un contenedor sin métodos. También debe tener en cuenta si está realizando la función Iniciar depuración o Iniciar sin depuración al iniciarlo en Visual Studio. El uso de Iniciar depuración enlaza muchas cosas para permitirle hacer pasos, ver valores, etc., y así puede tener un impacto de rendimiento significativo por sí mismo. – JamieSee
@dasblinkenlight - buen punto ... pero parece que las cosas buenas vienen de CLR, no compilador de C# ... Si fuera compilador, entonces también lo sería en VS. ... ¿Me falta algo aquí? –