views:

50

answers:

2

Hello,

i want to know if i could optimize the reflection part of my app.

Background information:

the vb.net windows application checks if database records apply on different rules. So i created an Interface iRule and (so far) 54 rules-classes that are implementing it. They all belong to the same project(Rule.dll). Because people should configure them to be active on specific conditions, there's also a table tabRule in Database where all these rules are listed(with RuleKey/RuleName etc.). This seems to be redundant but i haven't seen an alternative.

To come to the point:

I create instances of every Rule that is activated for the current record. Because the record count is avaraged 50000 and the rule-count is 54, the creation of the instances are time consuming. Do you have an idea(shared/static objects?) on how to optimze following part or suggestions for different approaches?

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

...and later for about 2700000 times ...

' 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....'

Thanks

+3  A: 

Could you pre-create instances of each rule, store them in a static dictionary keyed by Rule.GetKey, then when you need a new one, find the object in the dictionary and clone it?

At the beginning of your code that is going to iterate the 50000 rows, you can load each rule and stash it in the dictionary. Now you just have to iterate the rows, get the rule keys and clone the rules you need per row. The dictionary lookup will be light years faster than creating the object via reflection just to check its key.

Edit: Just thought of another possible solution. Do you have access to the Rule.dll, as in are you compiling, building this dll. In that case could you add a static helper class with a single static factory method that would take a rule.Key and return the appropriate IRule object. Then the only need for reflection would be to load this static class, then when iterating your rows you could just pass in the rule key and return back the appropriate rule object.

pstrjds
Precreating the rules, making sure you use a specific instance of the rule for each "combination" of options, is about the only way youre likely to make this faster
drventure
Sorry, then just cache the rules in a hash and connect them as you need them. Each Rule would need to be more or less stateless for this to work, which they should be anyway really.
drventure
+2  A: 

A really small improvement but instead of:

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

try:

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

You already have the type, so no need to search it once again inside the assembly.

Darin Dimitrov