This post demonstrates the speed advantage using CallFunctionFast() instead of Select/Case.
Both "Huge" loops effectively accomplish the same thing. Granted Select/Case is much simpler but... Compare times.
Code: Select all
;/ YOUR FAMILIAR, STANDARD, EVERY DAY "SELECT / CASE" SAMPLE CODE
; Going to test duration on "Select...Case Filtering" loop.
Global *a
capturedTime.i = ElapsedMilliseconds()
For l.i = 1 To 100000 ; Huge number of iterations to demonstrate concept.
For operation.w = 1 To 52 ; Using 52 operations here is arbitrary.
Select operation ; <<These "operation.i values" could also be random!!
Case 1 ; and same would apply to alternative method below.
dummy.i = dummy.i & 5
Case 2 ; Notice how ...
dummy.i = dummy.i & 5 ;The
Case 3
dummy.i = dummy.i & 5 ;more
Case 4
dummy.i = dummy.i & 5 ;Cases
Case 5
dummy.i = dummy.i & 5 ;there
Case 6
dummy.i = dummy.i & 5 ;are
Case 7
dummy.i = dummy.i & 5 ;the
Case 8
dummy.i = dummy.i & 5 ;less
Case 9
dummy.i = dummy.i & 5 ;efficient
Case 10
dummy.i = dummy.i & 5 ;Select
Case 11
dummy.i = dummy.i & 5 ;Case
Case 12
dummy.i = dummy.i & 5
Case 13
dummy.i = dummy.i & 5 ; Select/Case is a "filtering system"
Case 14 ; that must fail numerous tests before
dummy.i = dummy.i & 5 ; encountering matched values. Only
Case 15 ; after numurous failures, your code
dummy.i = dummy.i & 5 ; can then begin processing.
Case 16
dummy.i = dummy.i & 5
Case 17
dummy.i = dummy.i & 5 ; The alternative "direct jump" method
Case 18 ; always points to the exact fucntion
dummy.i = dummy.i & 5 ; without wasting any time "filtering".
Case 19
dummy.i = dummy.i & 5
Case 20
dummy.i = dummy.i & 5 ; For sample purposes, the functions
Case 21 ; used in each "Case value" have been
dummy.i = dummy.i & 5 ; kept identical (dummy=dummy & 5) to
Case 22 ; standardize comparisons.
dummy.i = dummy.i & 5
Case 23
dummy.i = dummy.i & 5
Case 24
dummy.i = dummy.i & 5
Case 25
dummy.i = dummy.i & 5
Case 26
dummy.i = dummy.i & 5
Case 27
dummy.i = dummy.i & 5
Case 28
dummy.i = dummy.i & 5
Case 29
dummy.i = dummy.i & 5
Case 30
dummy.i = dummy.i & 5
Case 31
dummy.i = dummy.i & 5
Case 32
dummy.i = dummy.i & 5
Case 33
dummy.i = dummy.i & 5
Case 34
dummy.i = dummy.i & 5
Case 35
dummy.i = dummy.i & 5
Case 36
dummy.i = dummy.i & 5
Case 37
dummy.i = dummy.i & 5
Case 38
dummy.i = dummy.i & 5
Case 39
dummy.i = dummy.i & 5
Case 40
dummy.i = dummy.i & 5
Case 41
dummy.i = dummy.i & 5
Case 42
dummy.i = dummy.i & 5
Case 43
dummy.i = dummy.i & 5
Case 44
dummy.i = dummy.i & 5
Case 45
dummy.i = dummy.i & 5
Case 46
dummy.i = dummy.i & 5
Case 47
dummy.i = dummy.i & 5
Case 48
dummy.i = dummy.i & 5
Case 49
dummy.i = dummy.i & 5
Case 50
dummy.i = dummy.i & 5
Case 51
dummy.i = dummy.i & 5
Case 52
dummy.i = dummy.i & 5
EndSelect
Next operation
Next l
MessageRequester("Select...Case Elaped Time",Str(ElapsedMilliseconds() - capturedTime.i))
;
;/ NOW THE ALTERNATIVE TO "SELECT / CASE FILTERING" AS SEEN ABOVE
;/ Initialize procedures that will correlate to "Case values"
; Array used to index what will be our "value dependant" procedure calls
Global Dim p.i(52)
Procedure test_a() ; CallFunctionFast() will be used later to call
dummy.i = dummy.i & 5 ; these procedures directly by numeric value.
EndProcedure ; This section equates 1 to 1 with the code above.
Procedure test_b()
dummy.i = dummy.i & 5 ; Procedures seen here are layed out and numbered
EndProcedure ; sequencially to match "Select/Case" equivilants
Procedure test_c() ; used in sample code above.
dummy.i = dummy.i & 5
EndProcedure
Procedure test_d()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_e()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_f()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_g()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_h()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_i()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_j()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_k()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_l()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_m()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_n()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_o()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_p()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_q()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_r()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_s()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_t()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_u()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_v()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_w()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_x()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_y()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_z()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_aa()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ab()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ac()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ad()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ae()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_af()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ag()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ah()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ai()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_aj()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ak()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_al()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_am()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_an()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ao()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ap()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_aq()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ar()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_as()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_at()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_au()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_av()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_aw()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ax()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_ay()
dummy.i = dummy.i & 5
EndProcedure
Procedure test_az()
dummy.i = dummy.i & 5
EndProcedure
; ;/ ; Initialize array for code demonstration below
p(1) = @test_a() ; Equivelent syntax under GFA_Basic for this operation
p(2) = @test_b() ; would be as follows:
p(3) = @test_c() ; ON operation GOSUB proc1, proc2, proc3, proc4, ...
p(4) = @test_d() ;
p(5) = @test_e() ; Could just as well be:
p(6) = @test_f() ; ON operation GOSUB left(), right(), bendover(), ...
p(7) = @test_g() ; ON operation GOSUB test_a(), test_b(), test_c(), ...
p(8) = @test_h() ;
p(9) = @test_i() ; The idea being procedures are called by corresponding
p(10) = @test_j() ; position following the term "Gosub". (1, 2, 3, ...)
p(11) = @test_k() ;
p(12) = @test_l() ; A comma delimnited list is not available in PureBasic
p(13) = @test_m() ; so instead we need to create our own index. That's
p(14) = @test_n() ; why we set up the procedures above. Now we index.
p(15) = @test_o() ;
p(16) = @test_p() ; The "@"procedure does the magic here by allowing each
p(17) = @test_q() ; procedure to be assigned a "Case value" according to
p(18) = @test_r() ; the procedure address in memory.
p(19) = @test_s()
p(20) = @test_t()
p(21) = @test_u()
p(22) = @test_v()
p(23) = @test_w()
p(24) = @test_x()
p(25) = @test_y()
p(26) = @test_z()
p(27) = @test_aa()
p(28) = @test_ab()
p(29) = @test_ac()
p(30) = @test_ad()
p(31) = @test_ae()
p(32) = @test_af()
p(33) = @test_ag()
p(34) = @test_ah()
p(35) = @test_ai()
p(36) = @test_aj()
p(37) = @test_ak()
p(38) = @test_al()
p(39) = @test_am()
p(40) = @test_an()
p(41) = @test_ao()
p(42) = @test_ap()
p(43) = @test_aq()
p(44) = @test_ar()
p(45) = @test_as()
p(46) = @test_at()
p(47) = @test_au()
p(48) = @test_av()
p(49) = @test_aw()
p(50) = @test_ax()
p(51) = @test_ay()
p(52) = @test_az()
; Test duration on "CallFunctionFast()" loop.
capturedTime.i = ElapsedMilliseconds()
Macro OnGosub
CallFunctionFast(*a) ;NOTE: the *a variable must be global
EndMacro
For l.i = 1 To 100000 ; Huge number of iterations to demonstrate concept.
For operation.w = 1 To 52
*a = p(1) ; Any value inside p() "means" call operation directly!!!
OnGosub ;NOTE: the *a variable must be global
;CallFunctionFast(*a) ; << JUST DO IT -- NO FILTERING REQUIRED !!!
Next operation
Next l
MessageRequester("CallFunctionFast() Elapsed Time",Str(ElapsedMilliseconds() - capturedTime.i))
