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:
The B4X compiler could do something like this:
The example above comes from the code snippet below. It's looping through a list grouping items by category.
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/
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.
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: