Page 1 of 1

ON <indexValue> GoProcedure

Posted: Sat Nov 19, 2005 5:00 am
by Randy Walker
Hi Fred,

Let me say first that I have made several references to GFA Basic in the past and I don't know if you find this reference annoying so I hope you will tell me if it does... thanks!

This sample code will I hope give you an idea what I am looking for. I think if you run it, examine the code and read the comments, it should be failry self explainitory. That said, I have no idea what it would take for you to construct a command to simulate this functionality, but I can tell you that the GFA command for this operation was also consideralby faster than the "Select...Case" alternative. Again, I have no idea how they did it, but the index array was not necessary to use the "ON n GOSUB" command. Also please note, the term "GOSUB" in GFA is used to call a procedure. Thanks again for taking a look. :)

[RE RE-EDITED 3/23/06] Also see "Faster than Select/Case": viewtopic.php?p=111941#111941

Code: Select all

 ;Better sample at link above (Faster than Salect/Case)
Dim p.l(9) ; Array used to index case dependant procedure calls using CallFunctionFast()
;
;/             For example sake, "Select...Case" and the "CallFunctionFast()" call
;/             will share these same "select" procedure calls. 
Procedure test_a()
  dummy.l = dummy.l & 5  ; same code in each proc for testing purposes
EndProcedure
Procedure test_b()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_c()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_d()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_e()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_f()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_g()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_h()
  dummy.l = dummy.l & 5
EndProcedure
Procedure test_i()
  dummy.l = dummy.l & 5
EndProcedure

;/             Index each of the procedure addresses into pointer array p().
;/             This additional code is required for the CallFunctionFast() call.
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 n GOSUB proc1, proc2, proc3, proc4, etc...
p(4) = @test_d() ; 
p(5) = @test_e() ; The value "n" above points to comma delimnited list 
p(6) = @test_f() ;  following the ON n GOSUB command so that direct
p(7) = @test_g() ; indexing by value is possible.  List items can be any 
p(8) = @test_h() ; order.  There is no "conditional" testing so processing
p(9) = @test_i() ; time is less than the "Select/Case"

;/             
;/               ; Initialize and get time on "Select...Case" loop.
;
capturedTime.l = ElapsedMilliseconds()
For l.w = 1 To 10000
  For c.w = 1 To 9
    Select 9
      Case 1
        test_a()  ;The
      Case 2
        test_b()  ;more
      Case 3
        test_c()  ;Cases 
      Case 4
        test_d()  ;the
      Case 5
        test_e()  ;less
      Case 6
        test_f()  ;efficient
      Case 7
        test_h()  ;Select
      Case 8
        test_h()  ;Case
      Case 9
        test_i()  ;is.
    EndSelect
  Next c
Next l
Debug "Select...Case Elaped Time"
Debug ElapsedMilliseconds() - capturedTime.l  ; post time for "Select...Case" loop.
;
Debug ""
;/
;/               ; Initialize and get time on "CallFunctionFast()" loop.
capturedTime.l = ElapsedMilliseconds()
For l.w = 1 To 10000
  For c.w = 1 To 9
    *a = p(c)        ; c.w is the index value for procedure call
    CallFunctionFast(*a)
  Next c
Next l
Debug "CallFunctionFast() Elapsed Time"
Debug ElapsedMilliseconds() - capturedTime.l  ; post time for "CallFunctionFast()" loop. 

Posted: Sat Nov 19, 2005 10:45 am
by Randy Walker
I show this line in the comments above as the GFA command structure.

Code: Select all

 ; ON n GOSUB proc1, proc2, proc3, proc4, etc... 
To look at it another way, I am using @test? as a placeholder in the line below.
Items in this list could be any procedure in any order. I'm guessing now that
maybe GFA inserted the procedure addresses something like this during compile:

Code: Select all

 ; ON n GOSUB @test?(), @test?(), @test?(), @test?(), etc... 
Thinking that might be why there is no need to collect procedure addresses into
an array as I have done using p(n). Please keep in mind I have no idea what I
am asking for in terms of fitting the actual details in so I wont hold my breath.

Maybe I'm looking for something like this:

Code: Select all

 ProcedureIndexCall(n, @test?(), @test?(), etc...) 
Hmmm. That means the length of the parameter list would vary according to the
applied use of the command. Maybe sticky, but I think it would beat Select/Case
in many instances where speed is a concern.
Then again maybe I'm looking at this all wrong and there is already a differnt command thats answers this request.

Posted: Thu Mar 23, 2006 2:27 pm
by Randy Walker
Fred ... you may have noticed I just updated my code ... I just did it again only moments ago. Code at the link above illustrates the concept much better. Of course now that I detailed an alternave, probably wont get the ON n GOSUB function from you :(

Just easier for me if you do all the work building indexes so I don't need to :)