小编bjq*_*inn的帖子

DynamicObject和TrySetMember性能与ExpandoObject性能

我正在使用DynamicObject的自定义实现,它非常适合我的应用程序,除了我遇到一些性能问题.在动态方面可以预期一些性能开销,但即使使用ExpandoObject,我也会看到显着的(读取:数量级)性能损失.

我不能使用ExpandoObject的原因是我想要覆盖它的一些行为.我把问题归结为下面一个非常简单的例子.

我的自定义ExpandoObject代码如下(简化为足以显示问题的代码) -

public class SuperExpando : DynamicObject
{
    public Dictionary<string, object> dictionary = new Dictionary<string, object>();
    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        dictionary[binder.Name] = value;
        return true;
    }
}

public dynamic m = new SuperExpando();
Run Code Online (Sandbox Code Playgroud)

当我在DynamicObject的字典直接设定值(iemdictionary ["键名"] = 500),那么我看到类似ExpandoObject,其是亚毫秒时间设置在字典中的密钥的值的性能.当我使用TrySetMember覆盖(iemkeyname = 500)时,我看到性能下降到30ms - 每个键值设置50ms.写入大量密钥时,这显然会成为一个问题.即使我一遍又一遍地写同一个密钥,通过TrySetMember访问它也需要相同的时间.

我的真实性能问题似乎与我使用动态的事实无关,因为它会影响TrySetMember.对于踢,我甚至评论了

dictionary[binder.Name] = value;
Run Code Online (Sandbox Code Playgroud)

在TrySetMember方法中,除了"return true;"之外什么都没有,而且性能是一样的.

如果我在SuperExpando类中添加如下内容 -

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
    if (dictionary.ContainsKey(binder.Name))
    {
        result = dictionary[binder.Name];
        return true;
    }
    return false; 
}
Run Code Online (Sandbox Code Playgroud)

通过TryGetMember访问(读取)变量的性能问题是相同的,而直接读取字典提供了合理的性能.

有任何想法吗?

-BJ奎因

编辑:这是完整的示例代码.只需创建一个表单并在其上放置一个运行go_Click事件的按钮,并将您的项目设置为控制台应用程序.对我来说,在ExpandoObject中设置所有50个键需要大约30ms,而SuperExpando至少需要750ms. …

c# dynamic expandoobject dynamicobject

4
推荐指数
1
解决办法
4691
查看次数

标签 统计

c# ×1

dynamic ×1

dynamicobject ×1

expandoobject ×1