【问题标题】:What is the performance hit with downcasting?向下转换对性能有何影响?
【发布时间】:2008-11-20 15:51:17
【问题描述】:

只是想通过阅读this enlightening article by Juval Lowy 来了解泛型

释义.. 当您定义一个 Generic 类定义时,它会被编译成 IL。

  • 对于值类型,只要您请求特定的值类型,它就会将 T 替换为您的特定值类型,以获得该特定配置的 IL,例如MyList<int> 好处:没有装箱和拆箱处罚。
  • 很好.. 对于引用类型,编译器将定义中的所有 T 实例替换为 Object 并创建用于所有引用类型的 IL。然而,实例是根据实际请求的 ref 类型分配的,例如MyList<String>

现在我们可以编写带有Object 参数的预泛型方法。泛型声称性能提高了 100%,因为“它避免了在你想使用它时将对象类型向下转换为特定类型时所招致的性能损失”

 // assume GetItem returns an Object
 string sMyPreciousString = (string) obList.GetItem(); 

当您从 Object 向下转换为特定引用类型时,这种性能会受到什么影响?此外,似乎向上转换为 Object(即使泛型也会这样做)不会影响性能。为什么?

【问题讨论】:

    标签: generics c#-2.0


    【解决方案1】:

    向上转换到对象不需要执行时间检查 - 它始终有效,并且基本上只是一个无操作。

    向下转换需要执行时间检查,以确保您没有将流转换为字符串。这是一个很小的惩罚,而且不太可能成为瓶颈 - 但避免它只是泛型的一个额外好处。

    【讨论】:

    • 当你知道它时简单...
    【解决方案2】:

    性能损失来自对运行时类型检查的需要。如果 B 是 A 的子类,那么当您将 B 转换为 A 时,您在编译时就知道它是安全的,因为所有 B 都是 As。因此,您无需生成任何运行时代码来检查类型。

    但是,当您将 A 转换为 B 时,您在编译时并不知道 A 是否实际上是 B。它可能只是一个 A,也可能是 C 类型,是 A 的不同子类型。因此,您需要生成运行时代码,以确保对象实际上是 B,如果不是则抛出异常。

    泛型没有这个问题,因为编译器在编译的时候就知道,只有Bs被放入了数据结构中,所以当你拉出一些东西的时候,编译器就知道它会是B,所以没有需要在运行时进行类型检查。

    【讨论】:

      【解决方案3】:

      阅读生成的 IL(article 提到了它)...啊哈 - isinst。

      如果你不沮丧,你就不必打电话给isinst

      【讨论】:

        猜你喜欢
        • 2011-09-16
        • 2015-03-04
        • 1970-01-01
        • 2019-09-04
        • 2021-04-20
        • 2016-09-26
        • 2011-11-12
        • 2014-01-05
        • 1970-01-01
        相关资源
        最近更新 更多