我知道,使用表達是比使用反射一個獲取屬性值快,我想轉換列表中的數據表,我已經用他們兩個,獲取屬性值的表達式不需要比反射更快嗎?
反射經過時間:36毫秒
表達經過時間:2350毫秒
我不知道我做錯了什麼呢?
我曾嘗試下面的代碼:
public class Foo
{
public long IntCode { get; set; }
public string Name { get; set; }
public string SurName { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
var r = new Random();
var foos = new List<Foo>();
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 10000; i++)
{
foos.Add(new Foo { IntCode = r.Next(), Name = Guid.NewGuid().ToString(), SurName = Guid.NewGuid().ToString(), Age = r.Next() });
}
sw.Stop();
Console.WriteLine("Elapsed Time For Creating : {0}", sw.ElapsedMilliseconds);
sw.Restart();
ConvertWithReflection(foos, "IntCode", "Name", "Age");
sw.Stop();
Console.WriteLine("Elapsed Time For Converting : {0}", sw.ElapsedMilliseconds);
sw.Restart();
ConvertWithExpression(foos, "IntCode", "Name", "Age");
sw.Stop();
Console.WriteLine("Elapsed Time For Converting : {0}", sw.ElapsedMilliseconds);
Console.ReadLine();
}
public static object GetValueGetter<T>(object item,string propertyName)
{
var arg = Expression.Parameter(item.GetType(), "x");
Expression expr = Expression.Property(arg, propertyName);
var unaryExpression = Expression.Convert(expr, typeof(object));
var propertyResolver = Expression.Lambda<Func<T, object>>(unaryExpression, arg).Compile();
var value = propertyResolver((T)item);
return value;
}
public static void ConvertWithReflection<T>(IEnumerable<T> list, params string[] columnNames)
{
var t = list.ToList();
if (!t.Any()) return;
var dataTable = new DataTable();
dataTable.Columns.Add("IntCode");
dataTable.Columns.Add("Name");
dataTable.Columns.Add("SurName");
dataTable.Columns.Add("Age");
foreach (var item in t)
{
var dr = dataTable.NewRow();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
var el = columnNames.ElementAtOrDefault(i);
if (el == null)
{
dr[i] = DBNull.Value;
}
else
{
var property = item.GetType().GetProperty(el);
dr[i] = property.GetValue(item, null);
}
}
dataTable.Rows.Add(dr);
}
}
public static void ConvertWithExpression<T>(IEnumerable<T> list, params string[] columnNames)
{
var t = list.ToList();
if (!t.Any()) return;
var dataTable = new DataTable();
dataTable.Columns.Add("IntCode");
dataTable.Columns.Add("Name");
dataTable.Columns.Add("SurName");
dataTable.Columns.Add("Age");
foreach (var item in t)
{
var dr = dataTable.NewRow();
for (var i = 0; i < dataTable.Columns.Count; i++)
{
var el = columnNames.ElementAtOrDefault(i);
if (el == null)
{
dr[i] = DBNull.Value;
}
else
{
dr[i] = GetValueGetter<T>(item, el);
}
}
dataTable.Rows.Add(dr);
}
}
}
什麼讓你覺得表達式應該更快?表達式使用反射...可以更快地生成和緩存委託並重用它,但是您的代碼每次都要重建和編譯委託,這需要很長時間。 – 2014-10-19 10:54:23
我明白了,我不知道如何緩存它,你可以做一個示例嗎? – sinanakyazici 2014-10-19 11:13:52