代码之家  ›  专栏  ›  技术社区  ›  Bob The Janitor

为什么.NET中的投射速度比反射速度快?

  •  10
  • Bob The Janitor  · 技术社区  · 15 年前

    我有一个事件处理程序,它需要确定一个类型,并在它与特定类型匹配时执行代码。最初我们将它转换为一个对象,如果它不是null,我们就执行代码,为了加快速度,我使用了反射,它实际上减慢了速度,我不明白为什么。

    下面是一个代码示例

    Trace.Write("Starting using Reflection");
    if (e.Item.GetType() == typeof(GridDataItem))
    {
          bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
          if (isWatch)
          {
              e.Item.Style["Font-Weight"] = "bold";
          }
     }
     Trace.Write("Ending using Reflection");
     Trace.Write("Starting using Cast");
     GridDataItem gridItem = e.Item as GridDataItem;
     if (gridItem !=null)
     {
         bool isWatch = Convert.ToBoolean(gridItem.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
         if (isWatch)
         {
             gridItem.Style["Font-Weight"] = "bold";
         }
      }
      Trace.Write("Ending using Cast"); 
    

    这是我得到的跟踪输出

    Starting using Reflection  0.79137944962406 0.576538
    Ending using Reflection    0.791600842105263    0.000221
    Starting using Cast    0.791623353383459    0.000023
    Ending using Cast      0.791649308270677    0.000026
    Starting using Reflection  0.876253801503759    0.084604
    Ending using Reflection    0.87631790075188 0.000064
    Starting using Cast    0.87633445112782 0.000017
    Ending using Cast      0.87634950075188 0.000015
    

    这不是很多,但如果我们不得不长期这么做的话,它可能会累积起来。

    6 回复  |  直到 14 年前
        1
  •  15
  •   Andrew Hare    15 年前

    反射很慢,因为您正在查询程序集的元数据,而强制转换只是更改您正在引用的对象的类型。

    程序集的元数据是一个有用的信息存储库,但最好在 编译时间 而不是在执行时。该元数据由编译器用于静态类型检查(除其他外)。您正在使用相同的元数据在执行时查找类型信息(如果您没有其他选择,这很好),这比强制转换要慢得多。

        2
  •  3
  •   kemiller2002    15 年前

    反射必须在运行时进行,并确定对象在运行时具有哪些属性等。强制转换告诉应用程序应该期望对象具有X属性,并且应该以某种方式运行。

        3
  •  2
  •   William Edmondson    15 年前

    强制转换告诉运行时您“知道”特定对象的类型。虽然您可能是错的,但运行时相信您,并且不会花费额外的时间来检查程序集的元数据。

        4
  •  1
  •   tvanfosson    15 年前

    你为什么不用这个 is operator ? 我认为它更可读,因为您没有显式强制转换,然后检查。它只是检查变量的类型是否正确。

    if (e.Item is GridDataItem)
    {
        bool isWatch = Convert.ToBoolean(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["IsWatch"]);
        if (isWatch)
        {
            e.Item.Style["Font-Weight"] = "bold";
        }
    }
    
        5
  •  1
  •   clemahieu    15 年前

        6
  •  0
  •   Piotr Niewinski    4 年前

    好吧,我想对最佳实践部分的一个简短回答是,如果你能用常规代码得到同样的结果,就永远不要使用反射。

    在优化代码时,通常最好估计优化所花费的时间将在哪里产生最大的性能增益。在语言中以本地方式重新实现操作符很少会排在列表的首位