我正在使用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. …