Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net VB 2010中的对象是否与C#4.0中的动态对象获得了相同的优化?_Vb.net_Visual Studio 2010_C# 4.0_Vb.net 2010 - Fatal编程技术网

Vb.net VB 2010中的对象是否与C#4.0中的动态对象获得了相同的优化?

Vb.net VB 2010中的对象是否与C#4.0中的动态对象获得了相同的优化?,vb.net,visual-studio-2010,c#-4.0,vb.net-2010,Vb.net,Visual Studio 2010,C# 4.0,Vb.net 2010,一些人认为,用dynamic关键字引入的C#4.0特性与VB的“一切都是对象”特性相同。但是,对动态变量的任何调用都将转换为委托一次,从那时起,将调用该委托。在VB中,当使用对象时,不应用缓存,对非类型化方法的每次调用都会涉及大量后台反射,有时会造成高达400倍的性能损失 是否已将添加到VB非类型化方法调用中,或者VB的非类型化对象仍然很慢?好问题。我猜答案是“不”,因为在MSDN杂志上说VB.Net已经被更改为支持动态语言运行时,并简要描述了运行时的更改,但没有提到缓存 有人知道得更清楚吗 引

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


是否已将添加到VB非类型化方法调用中,或者VB的非类型化对象仍然很慢?

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

有人知道得更清楚吗

引用以下内容:

Visual Basic 2010已更新为 完全支持DLR的功能 晚装

再清楚不过了。正是DLR实现了缓存。

解决方案 通过对Hans Passant提到的一些研究和更好的阅读,得出以下结论:

  • VB.NET 2010支持DLR
  • 如果希望显式支持动态,可以实现
    IDynamicMetaObjectProvider
    ,VB.NET编译器将更新以识别该动态
  • VB的
    对象
    只有在对象实现了
    IDynamicMetaObjectProvider
    时才会使用DLR和方法缓存
  • BCL和框架类型不实现
    IDynamicMetaObjectProvider
    ,在此类类型上使用
    Object
    ,或者您自己的类型将调用经典的非缓存VB.NET后期绑定器
背景:详细说明为什么后期绑定缓存有助于提高VB代码的性能 有些人(Hans Passant就是其中之一,请看他的答案)可能想知道为什么后期绑定中的缓存或非缓存可能很重要。实际上,它在VB和其他后期绑定技术(还记得
IQueryInterface
with 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
“在某个方法的主体中”
List listCustomers=GetListCustomers()
listCompanies=GetListCompanies()
listcustors.Sort(MySort.SortByName)
listCompanies.Sort(MySort.SortByName)
“排序功能”
公共共享函数SortByName(对象obj1、对象obj2)为整数
“为清晰起见,请检查是否删除了平等和虚无”
返回String.Compare(obj1.Name,obj2.Name)
端函数
这段代码(至少类似)实际上已经在我的一个客户机上投入生产,并在一个经常被称为AJAX的回调中使用。如果不手动缓存
.Name
属性(已经在不到50万个对象的中等大小列表中),后期绑定代码将成为一个明显的负担,最终导致整个站点崩溃。事实证明很难找到这个问题,但这是另一个时代的故事。修复后,该站点恢复了95%的CPU资源

因此,Hans的问题“你没有更大的问题要担心吗?”的答案很简单:这是一个大问题(或者可能是),特别是对于那些对使用后期绑定过于粗心的VB程序员来说

在这种特殊情况下,VB.NET 2010显然没有升级以引入后期绑定,因此,
对象对于不知情的人来说仍然是邪恶的,不应该与
动态
相比较


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

我也注意到了这一行,我喜欢你读这句话。要真正了解支持是否相等,我想我们需要测试、反向工程IL和测量性能。