He escrito algunos códigos de prueba para comparar el rendimiento del uso de acceso directo a la propiedad o la reflexión o reflexión mediante el uso de delegados. Pero los resultados que obtengo son desconcertantes, ya que muestran que la reflexión no es mucho más lenta (~ 4%) que el acceso directo a la propiedad, lo cual no creo que sea cierto. ¿Podría alguien decirme si estoy haciendo algo mal aquí?La prueba de reflexión no muestra los números esperados
de 5000 artículos que estoy consiguiendo los siguientes resultados
- acceso directo: 32.2609 segundos
- reflexión: 33.623 segundos reflexión de
- utilizando delegados: 31.7981 segundos
Código:
private static Random random = new Random((int)DateTime.Now.Ticks);
Private Dictionary<string, Delegate> delegateList = new Dictionary<string, Delegate>();
private List<ReflectClass1> dataList = new List<ReflectClass1>();
private void TestMethod2<T>()
{
foreach (var propertyInfo in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (propertyInfo.PropertyType.BaseType != typeof(ValueType))
{
Func<T, object> getPropDelegate =
(Func<T, object>) Delegate.CreateDelegate(typeof (Func<T, object>), null, propertyInfo.GetGetMethod());
delegateList.Add(propertyInfo.Name, getPropDelegate);
}
//else
//{
// Type propertyType = propertyInfo.PropertyType.GetType();
// delegateList.Add(propertyInfo.Name,
// Delegate.CreateDelegate(typeof(Func<T, TResult>), null, propertyInfo.GetGetMethod()));
//}
}
}
//http:_//stackoverflow.com/questions/1122483/c-random-string-generator
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
char ch;
for (int i = 0; i < size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
builder.Append(ch);
}
return builder.ToString();
}
private void SetUpReflectObjList()
{
for (int i = 0; i < 5000 ; i++)
{
ReflectClass1 reflectClass1 = new ReflectClass1();
reflectClass1.Prop1 = RandomString(15);
reflectClass1.Prop2 = RandomString(10);
reflectClass1.Prop3 = RandomString(10);
reflectClass1.Prop4 = RandomString(10);
reflectClass1.Prop5 = RandomString(10);
reflectClass1.Prop6 = RandomString(10);
reflectClass1.Prop7 = RandomString(10);
reflectClass1.Prop8 = RandomString(10);
reflectClass1.Prop9 = RandomString(10);
reflectClass1.Prop10 = RandomString(10);
dataList.Add(reflectClass1);
}
}
private void UseDelegateList()
{
Debug.WriteLine(string.Format(" Begin delegate performance test. item count = {0} start time: {1}",dataList.Count, DateTime.Now.ToLongTimeString()));
for (int i = 0; i < dataList.Count; i++)
{
foreach (PropertyInfo propertyInfo in typeof(ReflectClass1).GetProperties())
{
if (delegateList.ContainsKey(propertyInfo.Name))
{
Func<ReflectClass1, object> getPropDelegate = (Func<ReflectClass1, object>) delegateList[propertyInfo.Name];
Debug.Write(string.Format(" By delegates Object: {0} Property: {1} Value: {2}", i, propertyInfo.Name, getPropDelegate(dataList[i])));
}
}
}
Debug.WriteLine("");
Debug.WriteLine(string.Format(" End delegate performance test. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
}
private void UseDirectReflection()
{
Debug.WriteLine(string.Format(" Begin direct reflection performance test. item count = {0} start time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
for (int i = 0; i < dataList.Count; i++)
{
foreach (PropertyInfo propertyInfo in typeof(ReflectClass1).GetProperties())
{
if (propertyInfo == null) continue;
{
Debug.Write(string.Format(" By reflection Object: {0} Property: {1} Value: {2}", i, propertyInfo.Name, propertyInfo.GetValue(dataList[i], null)));
}
}
}
Debug.WriteLine("");
Debug.WriteLine(string.Format(" End direct reflection performance test. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
}
private void DirectOutputTest()
{
Debug.WriteLine(string.Format(" Begin direct output benchmark. item count = {0} start time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
for (int i = 0; i < dataList.Count; i++)
{
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop1", dataList[i].Prop1));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop2", dataList[i].Prop2));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop3", dataList[i].Prop3));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop4", dataList[i].Prop4));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop5", dataList[i].Prop5));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop6", dataList[i].Prop6));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop7", dataList[i].Prop7));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop8", dataList[i].Prop8));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop9", dataList[i].Prop9));
Debug.Write(string.Format(" direct output benchmark Object: {0} Property: {1} Value: {2}", i, "Prop10", dataList[i].Prop10));
}
Debug.WriteLine("");
Debug.WriteLine(string.Format(" End direct output benchmark. item count = {0} end time: {1}", dataList.Count, DateTime.Now.ToLongTimeString()));
}
Su punto de referencia es defectuoso. Está evaluando el lento 'string.Format' y las llamadas' Debug.Write' aún más lentas (lento en este contexto significa lento en comparación con el acceso directo a la propiedad y en comparación con la reflexión). –