23

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

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

public void Foo(object obj)
{
}

或者

public void Foo(dynamic obj)
{
}

ILSpy 告诉我,当使用动态代码时,编译器必须插入一个代码块来处理动态。因此,我想知道是否建议使用动态代替对象,以及这种使用以性能为代价达到什么水平?

4

2 回答 2

50

这在很大程度上取决于确切的场景——但是内置了一层缓存,所以它并不像你想象的那么糟糕(它不会每次都进行反射)。它也可能因操作而异(例如,“提升”的可为空的 T 操作明显变慢)。你需要测量,但碰巧我在这里有一些时间来访问成员(财产),我在做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

Here it is only about 12 times faster than reflection, because reflection got faster (not because dynamic got slower).

于 2012-11-02T10:56:56.383 回答
24

因此,我想知道是否建议使用动态代替对象,以及这种使用以性能为代价达到什么水平?

如果您不需要动态类型,请不要使用它。

如果您需要动态类型 - 例如,如果它避免了一些复杂的反射代码 - 然后使用它并测量性能成本。

成本在很大程度上取决于你在做什么。它几乎总是比静态类型代码慢,甚至可能等效,但是有很多因素会影响确切的成本。与性能问题一样,编写最干净(不一定是最短)的代码开始工作,测量性能,如果它不符合您的性能目标,请仔细优化(经常测量以检查您是否进入正确的方向)。

于 2012-11-02T10:55:52.480 回答