属性字典的速度比使用switch语句慢

3
我是一名有用的助手,可以翻译文本。

我目前有一个名为'ArisingViewModel'的类,其中包含约20-30个属性,在生成各种数据时将检查这些属性10,000多次。

最初,我有一个从XML字符串中检索出现属性值的方法,类似于:

    public object GetArisingPropertyValue(string propertyName)
    {
        switch (propertyName)
        {
            case "name_1":
                return Name1;
            case "another_name":
                return AnotherName;

            // etc.
        }
    }

但是为了更方便地更新和处理项目中的其他部分,这被改成使用属性字典。因此,我设置了如下的属性字典:

    private static readonly IDictionary<string, string> PropertyMap;


    static ArisingViewModel()
    {
        PropertyMap = new Dictionary<string, string>();

        var myType = typeof(ArisingViewModel);

        foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            if (propertyInfo.GetGetMethod() != null)
            {
                var attr = propertyInfo.GetCustomAttribute<FieldNameAttribute>();

                if (attr == null)
                    continue;

                PropertyMap.Add(attr.FieldName, propertyInfo.Name);
            }
        }
    }

我会像这样为任何相关的属性应用属性:

    [FieldName("name_1")]
    public string Name1
    {
        get
        {
            return _arisingRecord.Name1;
        }
    }

然后使用以下方法查找属性名称/值:

    public static string GetPropertyMap(string groupingField)
    {
        string propName;
        PropertyMap.TryGetValue(groupingField, out propName);
        return propName; //will return null in case map not found.
    }

    public static object GetPropertyValue(object obj, string propertyName)
    {
        return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
    }

我的问题是,我发现使用旧的switch语句处理速度要快得多(使用一个非常简单的计时器类来测量系统花费的时间 - 大约20秒对比大约25秒)。

有人能建议我做错了什么,或者有任何改进当前代码的方法吗?


将“属性”而非“属性名称”添加到字典中。 - Dmitry Bychenko
3
反射很慢(这里甚至为每次访问重复搜索属性)。如果在这种情况下存在问题,只需构建一个委托字典(而不是属性名称):Dictionary<string, Delegate>。 委托调用比第一种方法慢(如果属性数量不是很大),但是差异并不明显。您还可以尝试使用表达式和Reflection.Emit,但是...先测量一下! - Adriano Repetti
谢谢,我明白了。我会研究一下 Dictionary<string, delegate> 的方案,并看看它有多快,如果仍然很慢,那就回到 switch! - jimbo
1个回答

1
我建议实现一个类似于ObjectModelAdaptor的类,该类来自于StringTemplate 4的C#端口(BSD 3-clause许可证)。在模板呈现管道的性能关键部分中广泛使用此功能,并且分析表明当前实现的性能相当不错。
该类使用了一种相当有效的缓存和调度机制,尽管.NET 4+用户可以通过使用ConcurrentDictionary并删除lock语句来改进它。
您可能需要更改FindMember的实现以实现特定于具有属性的属性的逻辑。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接