在.NET中使用动态类型的性能成本

时间:2012-11-02 10:52:51

标签: c# .net performance dynamic compiler-construction

在.NET中使用dynamic vs object的性能成本是多少?比方说,我有一个接受任何类型参数的方法。 E.G。

public void Foo(object obj)
{
}

public void Foo(dynamic obj)
{
}

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

2 个答案:

答案 0 :(得分:46)

这在很大程度上取决于确切的情况 - 但内置了一层缓存,因此它并不像您预期​​的那样糟糕(它不会每次都进行反射)。它也可以根据操作而变化(例如,“提升”可空 - 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)

CAVEAT:这些是针对单个测试的,可能无法代表您的方案。此代码为shown here

所以:基于一个简单的测试,比静态普通C#慢大约20倍,但比反射快约30倍。

更新:有趣的是,看起来反射在.NET 4.5中变得更快:

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

这里它只比反射快约12倍,因为反射速度更快(不是因为动态变慢)。

答案 1 :(得分:22)

  

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

如果您不需要动态输入,请不要使用它。

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

成本严重取决于您正在做什么。它几乎总是比静态类型代码更慢,其中等效代码甚至可能,但有批次的因素会影响确切的成本。与性能问题一样,编写最干净(不一定是最短)的代码,开始使用,测量性能,如果不符合您的性能目标,请仔细优化(通过频繁的测量来检查您是否正在进行正确的方向)。