为什么创建和使用表达式要比直接访问更快?

问题描述 投票:1回答:1

我目前正在执行一些动态过滤/排序,并且认为进行基准测试以查看情况是个好主意。

首先,这是创建充当“ getter”的表达式的方法:

public static Expression<Func<TEntity, object>> GetPropertyGetter(string propertyName, bool useCache = false)
{
    if (useCache && _propertyGetters.ContainsKey(propertyName))
        return _propertyGetters[propertyName];

    var entityType = typeof(TEntity);
    var property = entityType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
    if (property == null)
        throw new Exception($"Property {propertyName} was not found in entity {entityType.Name}");

    var param = Expression.Parameter(typeof(TEntity));
    var prop = Expression.Property(param, propertyName);
    var convertedProp = Expression.Convert(prop, typeof(object));
    var expr = Expression.Lambda<Func<TEntity, object>>(convertedProp, param);

    if (useCache)
    {
        _propertyGetters.Add(propertyName, expr);
    }

    return expr;
}

这里是基准:

public class OrderBy
{

    private readonly List<Entry> _entries;

    public OrderBy()
    {
        _entries = new List<Entry>();
        for (int i = 0; i < 1_000_000; i++)
        {
            _entries.Add(new Entry($"Title {i}", i));
        }
    }

    [Benchmark(Baseline = true)]
    public List<Entry> SearchTitle()
    {
        return _entries.AsQueryable().OrderByDescending(p => p.Title).ToList();
    }

    [Benchmark]
    public List<Entry> SearchTitleDynamicallyWithoutCache()
    {
        var expr = DynamicExpressions<Entry>.GetPropertyGetter("Title");
        return _entries.AsQueryable().OrderByDescending(expr).ToList();
    }

    [Benchmark]
    public List<Entry> SearchTitleDynamicallyWithCache()
    {
        var expr = DynamicExpressions<Entry>.GetPropertyGetter("Title", useCache: true);
        return _entries.AsQueryable().OrderByDescending(expr).ToList();
    }

}

public class Entry
{

    public string Title { get; set; }
    public int Number { get; set; }

    public Entry(string title, int number)
    {
        Title = title;
        Number = number;
    }

}

这是结果:enter image description here

所以我的问题是,为什么创建一个表达式(使用反射来获取属性)要比直接访问(p => p.Title)更快?

c# .net-core benchmarking expression-trees
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.