【问题标题】:Performance dynamic vs Reflection性能动态与反射
【发布时间】:2018-05-21 09:43:11
【问题描述】:

我有以下可能检索列表中的值:

使用反射:

foreach (var item in items) {
  var property=item.Fields[fieldName].GetType().GetProperty("Id");
  var value=property.GetValue(item.Fields[fieldName]);
  if (value==searchValue) {
      filtered.Add(item);
   }
}

使用动态:

foreach (var item in items) {
   dynamic itemProperty=item.Fields[fieldName];
   if (itemProperty.Id==searchValue) {   
      filtered.Add(item);
   }
}

两个循环的作用相同。他们通过 Field[fieldName] 过滤 IEnumerable(或 List),它可以是不同的类型,但都包含一个名为“Id”的 int 属性。

我想知道哪个性能更好。 另外:将其中一个更改为 LinQ-Query 会提高性能吗?

【问题讨论】:

  • dynamic 也使用反射,但不像您在第一个示例中那样粗暴。所以我怀疑动态在这里会更快。当然,您也可以自己测量。
  • 有一个更简单的方法来处理这种场景 - 添加一个 interface IHasId { int Id {get; } } 并让你的类型实现它(因为隐式接口实现通常只是意味着添加 : IHasId 到每个).. . 然后foreach(IHasId item in items) { if (item.Id == searchValue) { ...} }
  • 你为什么不在一个足够大的集合上尝试一下呢?只需测量它,例如使用StopWatch。并且记住不要做premature optimization。也可以看看stackoverflow.com/questions/4646786/…

标签: c# performance linq dynamic reflection


【解决方案1】:

执行此 IMO 的最简单方法是定义一个具有 int Id {get;} 属性的接口并让您的类型实现它。然后对接口进行编码。如果您现有的代码是通用的,您甚至可以添加where T : IYourInterface 约束,但您可以转换为IYourInterface 任何一种方式(假设T 确实实现了该接口)。

如果接口不是一个选项:

Reflection 和dynamic 都有开销; dynamic 有更好的优化(重用缓存策略)。

如果您的items 列表被强类型化为特定的T(此处T 未知),那么您可以可能使用 LINQ 表达式进一步优化此概念以编译委托:

static class IdFetcher
{
    public static int Fetch<T>(T item) => IdFetcher<T>.Fetch(item);
}
static class IdFetcher<T>
{
    public static int Fetch(T item) => fetch(item);
    static readonly Func<T, int> fetch;
    static IdFetcher()
    {
        var p = Expression.Parameter(typeof(T), "item");
        fetch = Expression.Lambda<Func<T, int>>(
            Expression.PropertyOrField(p, "Id"), p).Compile();
    }
}

然后只需使用IdFetcher&lt;T&gt;.Fetch(obj)IdFetcher.Fetch(obj)(第一个更直接;第二个对于无法指定T 的匿名类型很有用)

除此之外:如果您想知道哪个更快:对它们进行计时(对于大量迭代)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2011-06-06
    • 2010-09-30
    • 2011-05-22
    • 1970-01-01
    • 2011-04-30
    • 2011-07-13
    相关资源
    最近更新 更多