使用`dynamic`和`object`的性能代价是什么?

25

在.NET中,使用 dynamic object 的性能成本是多少?

例如,假设我有一个接受任何类型参数的方法。例如:

public void Foo(object obj)
{
}
或者
public void Foo(dynamic obj)
{
}

ILSpy告诉我,使用动态代码时,编译器必须插入一个代码块来处理动态性。因此,我想知道是否建议在对象的位置使用dynamic关键字,并且这种用法在性能方面会带来什么样的代价?

2个回答

52
这将取决于具体的场景 - 但是已经内置了一层缓存,所以它并不像你想象的那么糟糕(它不会每次都进行反射)。它也可能因操作而异(例如,“提升”的可空-T操作明显较慢)。您需要进行测量,但恰好我在进行FastMember时对成员(属性)访问进行了一些计时,以下是结果:FastMember
Static C#: 14ms
Dynamic C#: 268ms
PropertyInfo: 8879ms (aka reflection)
PropertyDescriptor: 12847ms (aka data-binding)
TypeAccessor.Create: 73ms (aka FastMember)
ObjectAccessor.Create: 92ms (aka FastMember)

注意:这些仅适用于单个测试,可能不代表您的情况。此代码在此处显示。

所以:基于简单的测试,它比静态常规C#慢约20倍,但比反射快约30倍。

更新:有趣的是,在.NET 4.5中,反射似乎变得更快了:

Static C#: 13ms
Dynamic C#: 249ms
PropertyInfo: 2991ms
PropertyDescriptor: 6761ms
TypeAccessor.Create: 77ms
ObjectAccessor.Create: 94ms

这里只是相对于反射,动态获取的速度快了大约12倍,因为反射变得更快了(不是因为动态获取变慢了)。


1
您能否澄清一下 动态 C# 测试: 您是否测量了第一个调用的时间,还是后续(缓存的)调用的时间?我假设是前者,并且认为后续调用会更快,但不确定。(我知道我可以自己测试,但我相信未来的读者也会从这个澄清中受益 ;) ) - enzi

25
因此,我想知道在对象的地方使用dynamic是否值得推荐,并且在什么程度上这种用法会影响性能?
如果您不需要动态类型,就不要使用它。
如果您需要动态类型——例如,它可以避免某些复杂的反射代码——那么请使用它并测量性能成本。
成本将严重取决于您所做的确切操作。它几乎始终比相应的静态类型代码慢,但有许多因素可能影响确切成本。与任何性能问题一样,首先编写最干净(不一定是最短)的代码,测量性能,如果没有达到您的性能目标,则进行小心优化(频繁测量以检查您是否朝着正确的方向前进)。

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