Android Question Conditional Speed Test

stevel05

Expert
Licensed User
Longtime User
Not really a question but:

I have been working on an app that parses files of various sizes that I felt was taking too long, a 13kb file was taking about 14 seconds.

Looking for an explanation I decided to test the speed of for the conditional functions Select and If.

The code I used is:

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("1")

End Sub

Sub Activity_Resume


    Dim StartTime,EndTime As Long

    '#################################################################
    'Test 1
    '#################################################################

    Dim A(10) As Int = Array As Int(0,1,2,3,4,5,6,7,8,9)
    Dim B(10) As Int
    
    StartTime = DateTime.Now
    For i = 0 To 10000
        For j = 0 To A.Length -1
            Select A(j)
                Case 0
                    B(j) = B(j) + 1
                Case 1
                    B(j) = B(j) + 1
                Case 2
                    B(j) = B(j) + 1
                Case 3
                    B(j) = B(j) + 1
                Case 4
                    B(j) = B(j) + 1
                Case 5
                    B(j) = B(j) + 1
                Case 6
                    B(j) = B(j) + 1
                Case 7
                    B(j) = B(j) + 1
                Case 8
                    B(j) = B(j) + 1
                Case 9
                    B(j) = B(j) + 1
            End Select
        Next
    Next
    EndTime = DateTime.Now
    Label1.Text = "Test 1 Select Case : " & (EndTime - StartTime) & " ms"

    '#################################################################
    'Test 2
    '#################################################################

    Dim C(10) As Int = Array As Int(0,1,2,3,4,5,6,7,8,9)
    Dim D(10) As Int

    StartTime = DateTime.Now
    For k = 0 To 10000
        For l = 0 To C.Length -1
    
            If l = 0 Then D(l) = D(l) + 1
            If l = 1 Then D(l) = D(l) + 1
            If l = 2 Then D(l) = D(l) + 1
            If l = 3 Then D(l) = D(l) + 1
            If l = 4 Then D(l) = D(l) + 1
            If l = 5 Then D(l) = D(l) + 1
            If l = 6 Then D(l) = D(l) + 1
            If l = 7 Then D(l) = D(l) + 1
            If l = 8 Then D(l) = D(l) + 1            
            If l = 9 Then D(l) = D(l) + 1
        Next
    Next
    EndTime = DateTime.Now
    Label1.Text = Label1.Text & CRLF & CRLF & "Test 2 Multiple If : " & (EndTime - StartTime) & " ms"

    '#################################################################
    'Test 3
    '#################################################################

    Dim E(10) As Int = Array As Int(0,1,2,3,4,5,6,7,8,9)
    Dim F(10) As Int

    StartTime = DateTime.Now
    For m = 0 To 10000
        For n = 0 To E.Length -1
    
            If n = 0 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 1 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 2 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 3 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 4 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 5 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 6 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 7 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 8 Then
                F(n) = F(n) + 1
                Continue
            End If
            If n = 9 Then
                F(n) = F(n) + 1
                Continue
            End If
        Next
    Next
    EndTime = DateTime.Now
    Label1.Text = Label1.Text & CRLF & CRLF & "Test 3 Multiple If & Continue : " & (EndTime - StartTime) & " ms"



End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

I was totally surprised by the results, and have always used Select in multiple conditional situations, but none have been time critical until now.

I have used different variables for each test to try to make sure the data is not cached, and that the test is fair.

Could someone just sanity check the tests, to make sure.

I have tried running the tests in a different order with similar results.

A test project is attached if you want to run it.

In case you're just curious, a typical set of results on My Nexus 7 was:
Test 1 Select Case : 685 ms
Test 2 Multiple If : 28 ms
Test 3 multiple if & Continue : 22 ms

What is also interesting is to run the test in the different Debug/release modes.
 

Attachments

  • CondSpeedTest.zip
    7.4 KB · Views: 159

eps

Expert
Licensed User
Longtime User
I tested your version of the code, it ran as you indicated.

I tested with my change and Select works quite a bit quicker than IFs.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Internally Select is implemented in two modes. If the test value is an Int then the native select method is used (which only supports Ints). This method is the fastest.
Otherwise a different method is used which can handle any type of expression but is more expensive.
Try this:
B4X:
Dim n As Int = A(j)
Select n
 ...

As eps wrote your code is not 100% correct.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
B4X:
Dim n As Int = A(j)
Select n
...

Yep, that did it. Thanks

I thought it was a bit strange. I'll have to store that knowledge away somewhere accessible.:)


Out of interest typical results are now:

Test 1 Select Case : 22 ms
Test 2 Multiple If : 33 ms
Test 3 multiple if & Continue : 21 ms
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
When I use multiple If / Then tests I use
If j = 0 Then
Else If j = 1 Then
Else If j = 2 Then
'
End If

Yes, that's what I was changing my code to, until Erel gave his answer.

My only problem now is that the comparators are all hex literals, I have to change them all to int. but anything for speed.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
My app deals with bytes, so I had to change either the comparator to a signed byte or the test byte to an int with a value of 0 - 255, then the literals would work. I eventually decided to do the latter.
 
Upvote 0
Top