April 20, 2024, 02:15:16 AM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


Speeding things up

Started by Andy, March 28, 2020, 06:14:58 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Andy

Okay,

It's my usual silly question time!

Going back to programming basics, I understand calling a subroutine takes "some time", so is it faster to do what the subroutine is doing without calling it?

Example:

FOR a - 1 TO 10000
    DoThis()
NEXT a

or....

FOR a = 1 to 10000

    Line 1
    Line 2
    Line 3
    Line 4
    ..... Line X

NEXT a

My program will be calling the subroutine this say 4,000 times (could be 10,000 - in fact unknown).

Also, can I replace a FOR / NEXT loop with something faster, if so how?

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

jalih

Unrolling loop is an old code optimization technique. On modern processors it's probably not worth it and makes your code less readable. You can test if it makes a difference, I think it all depends how cache is utilized...

aurelCB

Try use pointered functions.
I used that method long time ago but i cannot remeber how ...
i think something with !myFunction()

aurelCB

Uff i found it ,it is called ,indirections

QuoteSubroutines 

Indirectly calling subroutines
Emergence BASIC supports indirectly calling subroutines through function pointers. A function pointer is a UINT variable that contains the address of a subroutine. The subroutine can be local or global. A common use for this is to create an array of subroutines, that all accept identical parameters, to be called by an index. The DECLARE statement needs to be used to set up a parameter template.
 
DECLARE fnTemplate(param as UINT),INT
You can use any valid name you wish for the template. After a subroutine is defined you can get the address of that subroutine using the & operator.
 
SUB Addition(param1 as FLOAT, param2 as FLOAT), FLOAT
    RETURN  param1 + param2
ENDSUB
 
SUB Subtraction(param1 as FLOAT, param2 as FLOAT), FLOAT
    RETURN param1 - param2
ENDSUB
 
DEF fnArray[2] as UINT
fnArray
  •  = &Addition
fnArray[1] = &Subtraction
Call the subroutine indirectly by using the ! operator, supplying the template name, variable containing the subroutine address, and any parameters
 
PRINT !<fnTemplate>fnArray
  • (1.0, 3.0)
    The DECLARE statement is only used as a template and will not look for a matching SUB when used as the parameter template for indirectly calling a subroutine. For a complete example see sample program: indirect_functions.eba
But i don't know if this work in IWB ?

Andy

Thanks Aurel,

Forgot about function pointers.

So I moved my subroutine to colour the words in a rich edit (on load) from my include file into the source program.

I then made a function call in a FOR /NEXT loop to it like this:

!<wpl2>fnArray[0](a+1,#tpl[a+1].TheText,#lp[a].LineS -1)

!<wpl2>fnArray[0] is pointing to the subroutine "WordPerLine2" (which actually does the colouring of words).

#tpl[a+1].TheText is a pointer to a string array that has the line of text to be coloured.

#lp[a].LineS -1 is a pointer to an integer array with the line's start index.

Together this made a difference of 0.6 seconds - doesn't sound a lot but it does make a difference!

Thanks,
Andy.
 :)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.