【发布时间】:2014-10-19 10:46:24
【问题描述】:
我知道使用表达式获取属性值比使用反射更快,我想将列表转换为数据表,我已经使用了它们,
反射经过时间:36 ms
表达式经过时间:2350 ms
我想知道我在那里做错了什么?
我试过下面的代码:
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);
}
}
}
【问题讨论】:
-
是什么让您认为表达式应该更快?表达式使用反射...可以更快的是生成和缓存委托并重用它,但是您的代码每次都在重建和编译委托,这需要很多时间。
-
我明白了,我不知道怎么缓存,能不能做个示例?
标签: c# performance reflection expression