VB 2010 中的 Object 是不是获得了与 C# 4.0 中的动态相同的优化?

Posted

技术标签:

【中文标题】VB 2010 中的 Object 是不是获得了与 C# 4.0 中的动态相同的优化?【英文标题】:Has Object in VB 2010 received the same optimalization as dynamic in C# 4.0?VB 2010 中的 Object 是否获得了与 C# 4.0 中的动态相同的优化? 【发布时间】:2011-02-07 09:02:50 【问题描述】:

有人争辩说,C# 4.0 中使用dynamic 关键字引入的特性与VB 的“一切都是对象”特性相同。但是,对动态变量的任何调用都将转换为一次委托,从那时起,将调用委托。在 VB 中,当使用 Object 时,没有应用缓存,并且对非类型化方法的每次调用都涉及大量的底层反射,有时总共会造成高达 400 倍的性能损失。

dynamic type delegate-optimization and caching 是否也被添加到了 VB 的无类型方法调用中,还是 VB 的无类型 Object 仍然这么慢?

【问题讨论】:

【参考方案1】:

解决方案

对 Hans Passant 提到的earlier referred to article 进行一些研究和更好地阅读,得出以下结论:

VB.NET 2010 支持 DLR; 如果您想显式支持动态,您可以实现IDynamicMetaObjectProvider,VB.NET 编译器已更新以识别这一点; VB 的Object 将仅在对象实现IDynamicMetaObjectProvider 时使用DLR 和方法缓存; BCL 和框架类型不实现 IDynamicMetaObjectProvider,在此类类型上使用 Object,否则您自己的类型将调用经典的非缓存 VB.NET 后期绑定器。

背景:详细说明为什么后期绑定缓存可以提高 VB 代码性能

有些人(其中包括 Hans Passant,请参阅他的回答)可能想知道为什么后期绑定中的缓存或非缓存可能很重要。实际上,它在 VB 和其他后期绑定技术中都有很大的不同(还记得 IQueryInterface 与 COM 吗?)。

后期绑定归结为一个简单的原则:给定一个名称及其参数声明,通过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

这段代码(至少是类似的)实际上是在我的一个客户那里投入生产的,并用于通常称为 AJAX 回调。如果没有手动缓存 .Name 属性,已经在不到 50 万个对象的中等大小的列表中,后期绑定代码成为如此明显的负担,最终导致整个站点崩溃。事实证明很难追查到这个问题,但这是另一个故事了。修复此问题后,该网站恢复了 95% 的 CPU 资源。

所以,对于 Hans 的问题“你没有更大的问题要担心” 的答案很简单:这是一个大问题(或可能是),尤其是。致那些对使用后期绑定过于粗心的 VB 程序员

在这种特殊情况下,以及许多类似的情况下,VB.NET 2010 显然还没有升级到引入后期绑定,因此,Object 对于不知情的人来说仍然是邪恶的,不应与dynamic 进行比较。

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

【讨论】:

【参考方案2】:

引用what's new article:

Visual Basic 2010 已更新为 完全支持 DLR 在其 后期粘合剂

没有比这更明确的了。实现缓存的是 DLR。

【讨论】:

我也注意到了这句话,我喜欢你对这句话的阅读。要真正知道支持是否相等,我想我们需要测试、逆向工程 IL 并测量性能。【参考方案3】:

好问题。我猜答案是“否”,因为 MSDN 杂志中的 this article 说 VB.Net 已更改为支持动态语言运行时,并简要描述了运行时的更改,但没有提及缓存。

有人知道吗?

【讨论】:

以上是关于VB 2010 中的 Object 是不是获得了与 C# 4.0 中的动态相同的优化?的主要内容,如果未能解决你的问题,请参考以下文章

vb.net 为 datagridviewcombobox 中的每个项目显示工具提示文本

在 VB.NET 中导致“导入中指定类型的命名空间不包含任何公共成员”的新 pc

VB2010中使用opentk的方法嘛

如何获取object.filter()django中的所有字段

是否有任何指示器可以知道OleDbDataAdapter是否根据提供的查询获得了记录?

使用VB6.0查找数组索引