Abe*_*bel 6 vb.net visual-studio-2010 vb.net-2010 c#-4.0
有人认为,dynamic关键字引入的C#4.0功能与VB的"一切都是对象"功能相同.但是,对动态变量的任何调用都将被转换为委托一次,从那时起,将调用委托.在VB中,当使用时Object,不应用缓存,并且对非类型化方法的每次调用都涉及大量的引擎盖反射,有时总共会产生高达400倍的性能损失.
是否已将动态类型委托优化和缓存添加到VB无类型方法调用中,或者VB的无类型对象仍然如此慢?
一些研究和更好的阅读前面提到的Hans Passant提到的文章,得出以下结论:
IDynamicMetaObjectProvider如果要显式支持动态,可以实现,VB.NET编译器更新以识别;Object只会在对象实现时使用DLR和方法缓存IDynamicMetaObjectProvider;IDynamicMetaObjectProvider,Object在这些类型上使用或者您自己的类型将调用经典的,非缓存的VB.NET后期绑定器.有些人(其中Hans Passant,见他的回答)可能想知道为什么缓存或非缓存在后期绑定中可能很重要.实际上,它在VB和其他后期绑定技术中都有很大的不同(请记住IQueryInterfaceCOM?).
后期绑定归结为一个简单的原则:给定一个名称及其参数声明,通过Type接口可用的方法(以及VB,方法,属性和方法)循环遍历此类的所有方法及其父类.字段可以看起来相同,使这个过程更慢).如果您认为方法表是无序的,那么这比单个直接(即,类型化)方法调用要昂贵得多.
如果您能够查找该方法一次,然后将方法指针存储在查找表中,这将大大加快此过程.DLR中的缓存方法绑定更进一步,如果可能的话,用指向实际方法的指针替换方法调用.在第一次通话之后,对于每次后续通话,这会变得快一个数量级(想想200倍到800倍的速度).
作为重要的一个例子,这里有一些代码说明了这个问题.在每个类都有.Name字符串属性但类不共享共同祖先或接口的情况下,您可以天真地对任何类型的列表进行排序,如下所示:
' 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
Run Code Online (Sandbox Code Playgroud)
这个代码(至少类似)实际上是用我的一个客户端生成的,并用于一个经常被称为AJAX的回调.没有手动缓存.Name属性,已经在不到五十万个对象的中等大小的列表上,后期绑定代码变得如此明显,最终导致整个网站崩溃.事实证明很难追查这个问题,但这是另一个故事.解决此问题后,该网站重新获得了95%的CPU资源.
因此,汉斯问题的答案"你不必担心更大的问题"很简单:这是一个大问题(或者可能是),尤其是.VB程序员对使用后期绑定过于粗心.
在这种特殊情况下,许多人喜欢它们,VB.NET 2010显然没有升级到引入后期绑定,因此,Object对于不知情的人来说仍然是邪恶的,不应该与之进行比较dynamic.
PS:后期绑定性能问题非常难以追踪,除非您有一个好的性能分析器并且知道编译器在内部如何实现后期绑定.
| 归档时间: |
|
| 查看次数: |
554 次 |
| 最近记录: |