代码之家  ›  专栏  ›  技术社区  ›  Abel

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

  •  6
  • Abel  · 技术社区  · 16 年前

    一些人认为,随着 dynamic 关键字与VB的“一切都是对象”功能相同。但是,对动态变量的任何调用都将被转换为委托,从那时起,将调用委托。在VB中,使用时 Object ,不应用缓存,对非类型化方法的每个调用都涉及大量的引擎盖下反射,有时总计高达400倍的性能损失。

    dynamic type delegate-optimization and caching 也被添加到vb的非类型化方法调用中,还是vb的非类型化对象仍然很慢?

    3 回复  |  直到 16 年前
        1
  •  5
  •   Abel    16 年前

    解决方案

    一些研究和更好的阅读 earlier referred to article 汉斯·帕桑特提到,得出如下结论:

    • vb.net 2010支持DLR;
    • 你可以实现 IDynamicMetaObjectProvider 如果您想要显式地支持动态,将更新vb.net编译器来识别它;
    • VB的 Object 仅在对象实现时使用DLR和方法缓存 IDynamicMetaObjectProvider ;
    • BCL和框架类型不实现 IDynamicMetaObjectProvider 使用 对象 对于此类类型或您自己的类型,将调用经典的、非缓存的vb.net后期绑定器。

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

    有些人(其中汉斯·帕桑特,见他的答案)可能会想,为什么在后期绑定中缓存或不缓存可能很重要。实际上,它在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回调中使用。不需要手动缓存 名字 属性已经在不到50万个对象的中等大小的列表中,后期绑定代码成为了一个明显的负担,最终导致整个站点瘫痪。事实证明,很难找到这个问题,但这是另一个故事。修复后,该站点恢复了95%的CPU资源。

    那么,汉斯问题的答案 “难道你没有更大的问题要担心吗?” 很简单:这是一个大问题(或者可能是),特别是对于那些太不注意使用后期绑定的VB程序员来说。

    在这种特殊情况下,很多人都喜欢vb.net 2010显然没有升级以引入后期绑定,因此, 对象 对不知情的人来说仍然是邪恶的,不应该与 dynamic .

    PS:后期绑定性能问题很难被跟踪,除非您有一个好的性能分析器,并且知道编译器内部实现的后期绑定有多晚。

        2
  •  2
  •   Hans Passant    16 年前

    引用 what's new article :

    Visual Basic 2010已更新为 在ITS中完全支持DLR 拉丁文

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

        3
  •  0
  •   MarkJ    16 年前

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

    有人更了解吗?

    推荐文章