Android Question Speed difference between Reflection library and For...Next

Tom_707

Member
Licensed User
How much of a speed penalty is there when using the reflection library?

For example, which of the following two methods is faster, and by how much? Is it negligible and doesn't make a difference, or is one method much better than the other?

Finding the correct View using reflection:
B4X: Copy
Dim refView As Reflector
Dim v As View

'Views have previously been assigned Tags
refView.Target = Activity
For Counter = 0 To 1000
   v = refView.RunMethod2("FindViewWithTag", Counter, "lang.java.int")
   v.Width = 100dip
Next


Finding the correct View by iterating through all Views:
B4X: Copy
Dim v As View

'Views have previously been assigned Tags
For Counter = 0 To 1000
   For Each v As View In Activity.GetAllViewsRecursive
      If v.Tag = Counter
         v.Width = 100dip
         Exit
      End If
   Next
Next
The "For Counter = 0 To 1000" loop is just there to magnify the speed difference. The real code will not have this.
 
You can add the code to your tests to time it yourself for example:

B4X: Copy
Dim refView As Reflector
Dim v As View

Dim StartTime as Long = DateTime.Now

'Views have previously been assigned Tags
refView.Target = Activity
For Counter = 0 To 1000
   v = refView.RunMethod2("FindViewWithTag", Counter, "lang.java.int")
   v.Width = 100dip
Next

Log(DateTime.Now - StartTime)

Will give you the time in milliseconds. Don't forget to test it in release mode.
 
Last edited:
Upvote 0
Reflection is normally a SL___OW process as it has to look up the required method from a list of those supported by the object then assemble the parameters and invoke the method. I guess you haven't run it as the correct name is findViewWithTag as Java is case sensitive.

Worrying about speed of execution is a premature optimisation. You should write nice, neat, understandable and well commented code and only be concerned when a problem arises. As a matter of style you should only use Reflection when necessary - after all you are writing in B4X not Java.
 
Upvote 0
You can add the code to your tests to time it yourself for example:

B4X: Copy
Dim refView As Reflector
Dim v As View

Dim StartTime as Long = DateTime.Now

'Views have previously been assigned Tags
refView.Target = Activity
For Counter = 0 To 1000
   v = refView.RunMethod2("FindViewWithTag", Counter, "lang.java.int")
   v.Width = 100dip
Next

Log(DateTime.Now - StartTime)

Will give you the time in milliseconds. Don't for get to test it in release mode.
Thanks @stevel05.
 
Upvote 0
Reflection is normally a SL___OW process as it has to look up the required method from a list of those supported by the object then assemble the parameters and invoke the method. I guess you haven't run it as the correct name is findViewWithTag as Java is case sensitive.

Worrying about speed of execution is a premature optimisation. You should write nice, neat, understandable and well commented code and only be concerned when a problem arises. As a matter of style you should only use Reflection when necessary - after all you are writing in B4X not Java.


Thanks @agraham. Appreciate your advice.

It's a pity "findViewWithTag" is not available in B4X. I think it would be really useful, and it doesn't seem like something that would be too difficult to implement.
 
Upvote 0
It's a pity .... is not available in B4X
Erel has to choose a balance between what is useful to most people and populating the language with stuff that is esoteric. It's a tightrope he has walked very well (in my opinion) for the last sixteen years in his products. The Reflection and JavaObject libraries (and more recently in-line Java) exist to let those with sufficient knowledge to break those bounds if necessary.
 
Upvote 0
This is a "preoptimization" thread.
Does it matter if it takes 0.1ms or 0.5ms to find a view? No user will ever see the difference.

If you want quick and elegant access to specific views then add them to a Map. Very simple to do.


I ran the following code twice:
B4X: Copy
    Dim refView As Reflector
    Dim strCounter As String
    Dim lbl As Label
    Dim StartTime As Long

    lbl.Initialize("")
    Activity.LoadLayout("Console")
    refView.Target = scvConsole.Panel
    For Counter = 0 To 10000
        Dim lblView As Label

        lblView.Initialize("")
        strCounter = Counter
        lblView.Tag = strCounter
        scvConsole.Panel.AddView(lblView, 0, Counter, 100dip, 30dip)
    Next
    StartTime = DateTime.Now
    For Counter = 0 To 10000
        strCounter = Counter
        lbl = refView.RunMethod2("findViewWithTag", strCounter, "java.lang.Object")
        lbl.Width = 150dip
    Next
    Log("R:" & (DateTime.Now - StartTime))
    StartTime = DateTime.Now
    For Counter = 0 To 10000
        strCounter = Counter
        For Each v As View In scvConsole.Panel.GetAllViewsRecursive
            If v.Tag = strCounter Then
                v.Width = 150dip
                Exit
            End If
        Next
    Next
    Log("F:" & (DateTime.Now - StartTime))


And got the following results:
Code: Copy
R:9779
F:17499
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
R:9685
F:17229
So if reflection is dog SL.....OW as @agraham says, then it shows how in-efficient it is to use a For...Next loop to iterate through all the Views. Which seemed obvious from the beginning. I'll try using a Map and see how that compares.
 
Upvote 0
So if reflection is dog SL.....OW as @agraham says, then it shows how in-efficient it is to use a For...Next loop
I didn't mean to imply in any paticular situation that Reflection would necessarily be slower - I meant in general. Here you are comparing using Reflection to call a single, native code, probably optimised, method against using many calls in a compiled loop. I still think this is totally unecessary, just code it the obvious understandable way, move on and come back to optimise it later when the app is finished if necessary.
 
Upvote 0
I didn't mean to imply in any paticular situation that Reflection would necessarily be slower - I meant in general. Here you are comparing using Reflection to call a single, native code, probably optimised, method against using many calls in a compiled loop. I still think this is totally unecessary, just code it the obvious understandable way, move on and come back to optimise it later when the app is finished if necessary.


Sorry, I didn't mean to malign your library, or reflection. I just assumed that using reflection was really slow, based on what you wrote. And because you created the library, you obviously would have a really good understanding of its speed performance.

I think your library is brilliant, and use it whenever there is something I can't achieve in B4X directly.
 
Upvote 0
Sorry, I didn't mean to malign your library,
I didn't for a moment think you were.

use it whenever there is something I can't achieve in B4X directly.
That was its original purpose, but it has become less important over the years as B4A has grown in capability, in particular with in-line Java, and Android performance has improved both with faster CPUs being available and with the switch from an interpreted virtual machine to a JIT capable virtual machine somewhere about Honeycomb.
 
Upvote 0
This is a "preoptimization" thread.
Does it matter if it takes 0.1ms or 0.5ms to find a view? No user will ever see the difference.

If you want quick and elegant access to specific views then add them to a Map. Very simple to do.


I added the following code:
B4X: Copy
    StartTime = DateTime.Now
    For Counter = 0 To 10000
        strCounter = Counter
        lbl = mapViews.Get(strCounter)
        lbl.Width = 150dip
    Next
    Log("M:" & (DateTime.Now - StartTime))


And here are the results:
Code: Copy
R:10366
F:17328
M:9
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
R:9581
F:17391
M:8


10ms using Maps vs 10s & 18s for the other two methods. The difference is absolutely staggering!!!
 
Last edited:
Upvote 0
Back
Top