Wish Improve Select/Case performance by front loading constant targets

stanmiller

Active Member
Licensed User
Longtime User
Wish - Improve Select/Case performance by front loading constant targets

The B4X compiler could improve Select/Case performance (sometimes exponentially) by front loading the case list when the targets are literals or constants.

Instead of this:
B4X:
switch (BA.switchObjectToInt(_sgrouper,"agg","dec","soi","mul","abo","cat")) {
  case 0:
     break;
  case 1:
    break;
}

The B4X compiler could do something like this:
B4X:
public int  _foo(anywheresoftware.b4a.objects.collections.List _lstcsv) throws Exception{
Object[] __b4atargets =  {"agg","dec","soi","mul","abo","cat"};

...

switch (BA.switchObjectToInt(_sgrouper,__b4atargets)) {
  case 0:
    break;
  case 1:
    break;
}

...

return 0;
}

The example above comes from the code snippet below. It's looping through a list grouping items by category.
B4X:
    ' Step through each row in list
    For Each aItemRow() As String In lstCsv
        Private product As PRODUCT_ITEM

        product.sCategory      = aItemRow( PRODUCT_CATEGORY      )
        product.sDescription   = aItemRow( PRODUCT_DESCRIPTION   )
        product.sDensityWeight = aItemRow( PRODUCT_DENSITYWEIGHT )

        sGrouper = product.sCategory.SubString2(0,3).ToLowerCase
        Select sGrouper
        Case "agg"
            lstAggregate.Add( product )
        Case "dec"
            lstDecorative.Add( product )
        Case "soi"
            lstSoil.Add( product )
        Case "mul"
            lstMulch.Add( product )
        Case "abo"
            ProductTableAbout = product.sDescription
            product = Null
        Case "cat"
            product = Null
        Case Else
            lstOther.Add( product )
            ErrorCode.SetErrorCode( ErrorCode.ERROR_UNKNOWN_CATEGORY )
        End Select
    Next

With a few loops and a handful of case targets you probably won't notice a difference. However, when a Select/Case has dozens of choices simply front-loading can yield orders of magnitude improvement.

The MteEval virtual machine is implemented using a Select/Case in a loop.

https://www.b4x.com/android/forum/t...-compiler-and-eval-library-open-source.70299/
B4X:
    ' Set instruction pointer
    nIP = CODE_STARTS_HERE

    Do While ( bRun )

        ' get op code
        nPcode = Code.get( nIP )

        ' Execute
        Select ( nPcode )

        Case PCODE.PUSH

            ' Advance stack pointer and store
            nSP = nSP + 1

            ' Overflow?
            If ( nSP > STACK_SIZE ) Then
                StackOverFlowError( oCodeBlock, nIP, nAX, nSP )
                Return ( 0 )
            End If

            aStack( nSP ) = nAX

            'Mtelog.Dbg( "<--- Push AX=" & nAX )

        Case PCODE.NEG

            nAX = - (nAX)

        Case PCODE.ADD

            nAX = aStack( nSP ) + nAX
            nSP = nSP - 1                     ' pop

        Case PCODE.SUBTRACT

            nAX = aStack( nSP ) - nAX
            nSP = nSP - 1                      ' pop

        ...

    Loop

There are 54 case targets (Pcodes). All of which are initialized B4X constants and their values do not change. Like the earlier example, the entire case list is reloaded with each loop. This could benefit from front-loading as well.
B4X:
BA.switchObjectToInt((_npcode),_pcode._push,_pcode._neg,_pcode._add,_pcode._subtract,
_pcode._multiply,_pcode._divide,_pcode._modulo,_pcode._logical_or,_pcode._logical_and,
_pcode._logical_not,_pcode._equal,_pcode._not_equal,_pcode._less_than,_pcode._less_equ
al,_pcode._greater_than,_pcode._greater_equal,_pcode._bit_and,_pcode._bit_or,_pcode._b
it_xor,_pcode._bit_not,_pcode._bit_shift_left,_pcode._bit_shift_right,_pcode._jump_always,
_pcode._jump_false,_pcode._jump_true,_pcode._loadconst,_pcode._loadvar,_pcode._store
var,_pcode._func_abs,_pcode._func_max,_pcode._func_min,_pcode._func_sqrt,_pcode._fun
c_power,_pcode._func_round,_pcode._func_floor,_pcode._func_ceil,_pcode._func_cos,_pco
de._func_cosd,_pcode._func_sin,_pcode._func_sind,_pcode._func_tan,_pcode._func_tand,_
pcode._func_acos,_pcode._func_acosd,_pcode._func_asin,_pcode._func_asind,_pcode._func
_atan,_pcode._func_atand,_pcode._func_number_format,_pcode._func_avg,_pcode._endco
de))
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…