Я написал тестовый код для сравнения производительности использования прямого доступа к свойству или отражения или отражения с использованием делегатов. Но результаты, которые я получаю, сбивают с толку, поскольку они показывают, что рефлексия не намного медленнее (~ 4%), чем прямой доступ к собственности, что я не считаю верным. Может ли кто-нибудь сказать мне, если я делаю что-то здесь не так?
для 5000 наименований Я получаю следующие результаты
- прямой доступ: 32,2609 с
- отражение: 33,623 с отражение
- с использованием делегатов: 31,7981 с
Код:
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()));
}