IonicWind Software

IWBasic => General Questions => Topic started by: Andy on March 28, 2020, 06:14:58 AM

Title: Speeding things up
Post by: Andy on March 28, 2020, 06:14:58 AM
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.
Title: Re: Speeding things up
Post by: jalih on March 28, 2020, 10:14:33 AM
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...
Title: Re: Speeding things up
Post by: aurelCB on March 28, 2020, 11:19:06 AM
Try use pointered functions.
I used that method long time ago but i cannot remeber how ...
i think something with !myFunction()
Title: Re: Speeding things up
Post by: aurelCB on March 28, 2020, 11:25:11 AM
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 ?
Title: Re: Speeding things up
Post by: Andy on March 29, 2020, 02:57:59 AM
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.
 :)