在VB 2010中的对象与C#4.0中的动态相同的最佳化吗? [英] Has Object in VB 2010 received the same optimalization as dynamic in C# 4.0?

查看:123
本文介绍了在VB 2010中的对象与C#4.0中的动态相同的最佳化吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些人认为使用动态关键字引入的C#4.0功能与VB的一切都是对象功能相同。但是,对动态变量的任何调用都将被转换为一个委托,从那时起,委托将被调用。在VB中,当使用 Object 时,不应用缓存,并且对非类型方法的每个调用都涉及大量的引擎底层反射,有时总共有400个非常严重的性能损失。



动态类型委托优化和缓存也被添加到VB的非类型化方法调用,还是VB的无类型对象仍然这么慢?

解决方案

解决方案



a href =http://msdn.microsoft.com/en-us/magazine/ee336123.aspx =nofollow>早前提到Hans Passant提到的第条,得出以下结论: / p>


  • VB.NET 2010支持DLR;

  • 您可以实现 IDynamicMetaObjectProvider 如果要明确支持动态,则更新VB.NET编译器以识别;

  • VB的对象将只使用DLR和方法缓存,如果对象实现 IDynamicMetaObjectProvider ;

  • BCL和框架类型不实现 IDynamicMetaObjectProvider ,在这种类型或你自己的类型上使用 Object 将调用经典的非缓存的VB.NET延迟绑定。 / li>


背景:阐述为什么后期绑定缓存可以帮助VB代码性能



有些人(其中Hans Passant,见他的回答)可能想知道为什么缓存或非缓存在后期绑定可能是重要的。实际上,它在VB和其他后期绑定技术(记住 IQueryInterface with COM?)有很大的区别。



迟绑定归结于一个简单的原则:给定一个名称及其参数声明,通过方法循环遍历该类及其父类的所有方法通过类型接口(在VB中,方法,属性和字段可以看起来,这使得这个过程甚至更慢)。如果你认为方法表是无序的,那么这比单个直接(即类型化)方法调用要容易得多。



如果你能够查找该方法一次,然后将方法指针存储在查找表中,这将大大加快这一过程。 DLR中的缓存方法绑定更进一步,如果可能,用指向实际方法的指针替换方法调用。在第一次调用之后,对于每个后续调用,这将变得更快一个数量级(认为200x到800x倍更快)。



作为一个例子,说明此问题的代码。在每个类都有一个 .Name string属性的情况下,但是这些类不共享一个共同的祖先或接口,你可以天真地排序任何这些类型的列表, :

 '在某些方法的主体中
List< Customers> listCustomers = GetListCustomers()
List< Companies> listCompanies = GetListCompanies()

listCustomers.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)

'排序函数'
Public共享函数SortByName(Object obj1,Object obj2)As Integer
'为了清楚起见,检查相等和无关删除'
return String.Compare(obj1.Name,obj2.Name)
End函数

此代码(至少类似)实际上使其与我的一个客户生产,在一个常被称为AJAX回调。没有手动缓存 .Name 属性,已经在不到50万个对象的中等大小的列表中,后期绑定代码变得如此明显的负担,最终带来了整体网站下来。它证明很难追踪这个问题,但这是一个故事另一个时间。修复此问题后,网站重新获得了95%的CPU资源。



所以,汉斯的问题的回答你不需要担心更大的问题很简单:这是一个大问题(或可以),esp。对于使用后期绑定太麻烦的VB程序员。



在这个特殊情况下,许多人喜欢他们,VB.NET 2010显然没有升级到介绍后缀绑定,因此, Object 对于不知道仍然是邪恶的,不应与动态进行比较。 p>

PS:后期绑定的性能问题很难跟踪,除非你有一个良好的性能分析器,并知道如何由编译器内部实现后期绑定。


Some people have argued that the C# 4.0 feature introduced with the dynamic keyword is the same as the "everything is an Object" feature of VB. However, any call on a dynamic variable will be translated into a delegate once and from then on, the delegate will be called. In VB, when using Object, no caching is applied and each call on a non-typed method involves a whole lot of under-the-hood reflection, sometimes totaling a whopping 400-fold performance penalty.

Have the dynamic type delegate-optimization and caching also been added to the VB untyped method calls, or is VB's untyped Object still so slow?

解决方案

Solution

Some research and a better reading of the earlier referred to article mentioned by Hans Passant, brings about the following conclusion:

  • VB.NET 2010 supports the DLR;
  • You can implement IDynamicMetaObjectProvider if you want to explicitly support dynamics, the VB.NET compiler is updated to recognize that;
  • VB's Object will only use the DLR and method caching if the object implements IDynamicMetaObjectProvider;
  • BCL and Framework types do not implement IDynamicMetaObjectProvider, using Object on such types or your own types will invoke the classical, non-cached VB.NET late-binder.

Background: elaborating on why late-binding caching could help VB code performance

Some people (among whom Hans Passant, see his answer) may wonder why caching or non-caching in late-binding could possibly matter. Actually, it makes a large difference, both in VB and in other late-binding technologies (remember IQueryInterface with COM?).

Late-binding comes down to a simple principle: given a name and its parameter-declarations, loop through all the methods of this class and its parent classes by means of methods available though the Type interface (and in VB, a method, a property and a field can look the same, making this process even slower). If you consider that method tables are unordered, then this is easily much more expensive than a single direct (i.e., typed) method call.

If you were capable of looking up the method once, and then storing the method-pointer in a lookup table, this would greatly speed up this process. Cached method binding in the DLR goes one step futher and replaces the method-call with a pointer to the actual method, if possible. After the first call, this becomes an order of magnitude faster for each subsequent call (think 200x to 800x times faster).

As an example of when this matters, here's some code that illustrates this issue. In a case where every class has a .Name string property, but the classes do not share a common ancestor or interface, you can naively sort lists of any of those types like so:

' in the body of some method '
List<Customers> listCustomers = GetListCustomers()
List<Companies> listCompanies = GetListCompanies()

listCustomers.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)

' sorting function '
Public Shared Function SortByName(Object obj1, Object obj2) As Integer
    ' for clarity, check for equality and for nothingness removed '    
    return String.Compare(obj1.Name, obj2.Name)    
End Function

This code (similar at least) actually made it into production with one of my clients and was used in an often-called AJAX callback. Without manually caching the .Name properties, already on medium sized lists of less than half a million objects, the late-binding code became such a noticeable burden that it eventually brought the whole site down. It proved hard to track down this issue, but that's a story for another time. After fixing this, the site regained 95% of its CPU resouces.

So, the answer to Hans's question "don't you have bigger problems to worry about" is simple: this is a big problem (or can be), esp. to VB programmers who have gotten too careless about using late-binding.

In this particular case, and many like them, VB.NET 2010 has apparently not been upgraded to introduce late-binding, and as such, Object remains evil for the unaware and should not be compared with dynamic.

PS: late-binding performance issues are very hard to track down, unless you have a good performance profiler and know how late-binding is implemented internally by the compiler.

这篇关于在VB 2010中的对象与C#4.0中的动态相同的最佳化吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆