代码之家  ›  专栏  ›  技术社区  ›  Tim Schmelter

反射:优化性能

  •  0
  • Tim Schmelter  · 技术社区  · 14 年前

    我想知道我是否可以优化我的应用程序的反射部分。

    背景信息:

    vb.net windows应用程序检查数据库记录是否应用于不同的规则。所以我创建了一个接口 iRule 到目前为止,有54个规则类正在实现它。它们都属于同一个项目(Rule.dll)。因为人们应该将它们配置为在特定条件下处于活动状态,所以数据库中还有一个表tabRule,其中列出了所有这些规则(带有RuleKey/RuleName等)。这似乎是多余的,但我没有看到其他选择。

    说到重点:

    我创建为当前记录激活的每个规则的实例。因为记录计数是avarag50000,规则计数是54,所以创建实例非常耗时。你有什么想法(共享/静态对象?)如何针对不同的方法优化以下部分或建议?

    Dim asmRule As System.Reflection.Assembly = System.Reflection.Assembly.LoadFrom(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rule.dll"))
    

    ……后来大约有2700000次。。。

    ' Find the rule in the rules assembly'
    Dim ruleObj As Rule.IRule = Nothing, found As Boolean = False
    For Each typeAsm As System.Type In asmRule.GetTypes
        If typeAsm.GetInterface(GetType(Rule.IRule).FullName) IsNot Nothing Then
            ruleObj = CType(asmRule.CreateInstance(typeAsm.FullName, True), Rule.IRule)
            If ruleObj.GetKey = ruleRow.RuleKey Then 'ruleRow is the db-counterpart of the rule class'
                found = True
                Exit For
            End If
        End If
    Next
    '..... execute rule if found....'
    

    谢谢

    3 回复  |  直到 14 年前
        1
  •  3
  •   pstrjds    14 年前

    能否预先创建每个规则的实例,将它们存储在rule.GetKey设置键的静态字典中,然后在需要新实例时,在字典中找到该对象并克隆它?

    在要迭代50000行的代码的开头,可以加载每个规则并将其保存在字典中。现在您只需迭代行,获取规则键并克隆每行所需的规则。字典查找将比仅仅通过反射来检查其键来创建对象快几光年。

    编辑:只是想到了另一个可能的解决方案。您是否有权访问Rule.dll,就像您正在编译、生成此dll一样。在这种情况下,您可以添加一个静态助手类,其中包含一个静态工厂方法,该方法接受rule.Key并返回适当的IRule对象。然后,反射的唯一需要是加载这个静态类,然后在迭代行时,只需传入规则键并返回适当的规则对象。

        2
  •  2
  •   Darin Dimitrov    14 年前

    一个非常小的改进,但不是:

    ruleObj = CType(asmRule.CreateInstance(typeAsm.FullName, True), Rule.IRule)
    

    尝试:

    ruleObj = CType(Activator.CreateInstance(typeAsm, True), Rule.IRule)
    

    您已经拥有该类型,因此无需在程序集中再次搜索它。

        3
  •  0
  •   NicoJuicy    13 年前

    尝试实现此功能:)

    系统。反射是“重磅”,我总是先实现一个更轻的方法。。

    //C类#

    if (item is IEnumerable) {
        foreach (object o in item as IEnumerable) {
                //do function
        }
    } else {
        foreach (System.Reflection.PropertyInfo p in obj.GetType().GetProperties())      {
            if (p.CanRead) {
                Console.WriteLine("{0}: {1}", p.Name, p.GetValue(obj,  null)); //possible function
            }
        }
    }
    

    VB.NET

      If TypeOf item Is IEnumerable Then
    
        For Each o As Object In TryCast(item, IEnumerable)
                   'Do Function
         Next
      Else
        For Each p As System.Reflection.PropertyInfo In obj.GetType().GetProperties()
             If p.CanRead Then
                   Console.WriteLine("{0}: {1}", p.Name, p.GetValue(obj, Nothing))  'possible function
              End If
          Next
      End If