0

I have been reading up on Reflection and it seems to be a good fit for my application but I have some concerns, mainly around performance. Here is my class below. MyObject may get created 20 times per page request which means CreateInstance will execute only around 20 times per page, max. Question 1: Can I be happy with this in that this does not effect performance in such a significant way?

My main concern is that RunFunction may be called 100's of times per page request. So, Question 2: Is this going to hurt performance and is there a better way of doing this if it does?

My application does know about all the Classes that are named in SomeClassName, but it just doesn't know WHEN to execute the objDynamic functions until runtime.

Question 3: Have their been significant improvements in .net 4.0 for Reflection performance?

Thanks for your time with this.

Class MyObject
    dim objDynamic as object = nothing
    public sub new(SomeClassName as String)
        objDynamic = Activator.CreateInstance(Type.[GetType](SomeClassName))
    end sub

Public function RunFunction(strFunctionName As String) As Object
    Dim thisType As Type = objDynamic.[GetType]()

    Dim theMethod As System.Reflection.MethodInfo = thisType.GetMethod(strFunctionName)

    dim objResult as Object = theMethod.Invoke(objDynamic, nothing)

return objResult
End Function

end class

Edit: What if I did this...

Class MyObject
    dim objDynamic as object = nothing
    Public bolMethodInfo As New List(Of System.Reflection.MethodInfo)
    public sub new(SomeClassName as String)
        objDynamic = Activator.CreateInstance(Type.[GetType](SomeClassName))
    end sub

Public function RunFunction(strFunctionName As String) As Object
    Dim thisType As Type = objDynamic.[GetType]()

    Dim theMethod As System.Reflection.MethodInfo = Nothing 
    For Each mi As System.Reflection.MethodInfo In bolMethodInfo
        If mi.Name = strFunctionName Then
            theMethod = mi
            Exit For
        End If
    Next

    If theMethod Is Nothing Then
        theMethod = thisType.GetMethod(strFunctionName)
        bolMethodInfo.Add(theMethod)
    End If

    dim objResult as Object = theMethod.Invoke(objDynamic, nothing)

return objResult
End Function

end class
Mike
  • 91
  • 1
  • 1
  • 9
  • 1
    Where do the type and function names come from? Can you change your approach so that you don't need to rely on reflection when the application runs? E.g. keep a mapping from string to delegates that create your object and run the function. – fsimonazzi Dec 10 '13 at 15:07
  • In my app, a XML markup block is loaded in and embedded in this is the name of the Type and the Function name that should execute (perhaps hundreds of times). I am not sure how to map a string to a delegate and run the function etc which would replace my code above. – Mike Dec 10 '13 at 15:23
  • So I have added another piece of code. If it is the retrieval of MethodInfo which takes the most time, can I not just store it locally. If it gets run a hundred times per page then it gets the MethodInfo once and just retrieves it from the bolMethodInfo if it exists effectively reusing it for the other 99 times? Please see the edited code. – Mike Dec 10 '13 at 16:36
  • Is it possible to continue this thread. Could you comment on this second block of code and also provide via a link or enter code here of an example to a really simple way of implementing a delegate. Thank you. – Mike Dec 11 '13 at 12:07
  • you can create a delegate using the CreateDelegate method http://msdn.microsoft.com/en-us/library/74x8f551(v=vs.110).aspx but it will only work if you know the exact signature of the delegate type. Regarding the second sample you probably want to use a dictionary rather than a list and key on method name. You also need to make sure you deal with thread safety. But more importantly, as I asked originally, where do the type and method names come from? If they are known at compile time, couldn't you try a different approach which didn't rely on strings? – fsimonazzi Dec 11 '13 at 13:50
  • The XML is loaded dynamically at runtime so although the Classes are compiled already, I won't know which Class and Function to run until I have loaded in the XML. It feels like to me, that Class and Function are dependent on User input, e.g. if User chooses Option A, run Function A, elseif user chooses Bption B, run Function Betc, which can of course be hard coded but feels cumbersome. – Mike Dec 11 '13 at 14:34

2 Answers2

1

This (second answer) proposes a way to use reflection and cut through the costs.

Community
  • 1
  • 1
Francis Ducharme
  • 4,848
  • 6
  • 43
  • 81
0

Early optimization is the root of all evil. Try profiling your application, and see if you are trying to optimize the right piece of code. Executing something 20 times is usually not a lot, 200000 times is. Depends on the case, of course, so profile first, and then decide. Yes, switching to Reflection can be faster, up to 10 times, if done right, IIRC. But the maintenance nightmare it causes is not worth it (most of the time).

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
  • I can appreciate that because if you optimised perfectly, no project would ever get finished, however, when there is a fundamental flaw in the way you are doing it, then there is an issue. Can I assume that from what you have read so far, the approach is not a fundamental flaw, but a perfectly acceptable approach? – Mike Dec 11 '13 at 11:59
  • @Mike: Yes, reflection is acceptable, but should only be regarded as a last resort, if you could not work it out through other methods. – Victor Zakharov Dec 11 '13 at 12:16
  • @Mike: What I mean by that - if your original code A) needs to be optimized (profile hard, before you decide) B) can be optimized by removing reflection from it, then do so. If A still applies and B does not, you are free to cache your reflection calls. Just make sure A applies. – Victor Zakharov Dec 11 '13 at 12:26
  • Thanks for the clarity. If my Type and Function names are held in XML, then I can see no other option than to use Reflection. Is there another way given that the Type and Function name is retrieved from the XML? – Mike Dec 11 '13 at 13:15
  • @Mike: If it's XML, I think reflection is the only way, unfortunately. Whenever you deal with function and/or type names stored in plain text, reflection comes up. The idea is to avoid this, for example, if you want to customize your business logic and processing like this, consider using data tables, or any other data storage. So you have fixed calls, but dynamic rules/workflow. If it's a third party XML you need to process, then yes, there is nothing you can do, but keep using reflection. – Victor Zakharov Dec 11 '13 at 13:54
  • Why would using data tables be any better? It still come out as plain text doesn't it and I am dealing with the same issue? Or have I misunderstood what you are saying? – Mike Dec 11 '13 at 14:39
  • @Mike: You need to invent a framework, which would suit your needs. The goal is to abstract workflow from the framework, so you don't call objects and functions, you actually define a workflow in close-to-human language and terms. Coming from the insurance world, I can tell you this is hard, but not impossible. One trick you may want to know here is that not every possible combination of object/function calls make sense, in fact 99.99% of them don't. By allowing all of them to be called, you are increasing complexity of the problem, and possible maintenance effort later. – Victor Zakharov Dec 11 '13 at 14:43