Topic : The GFA-Basic Compendium Author : GFA Systemtechnik GmbH Version : GFABasic.HYP v2.98 (12/31/2023) Subject : Documentation/Programming Nodes : 899 Index Size : 28056 HCP-Version : 3 Compiled on : Atari @charset : atarist @lang : @default : Document not found @help : Help @options : +g -i -s +z @width : 75 @hostname : STRNGSRV @hostname : CAB @hostname : HIGHWIRE @hostname : THING View Ref-FileSo far we have only considered arithmetic operations on two variables. Now we must look at operations involving more than two variables. The compiler can only translate such operations into code which does not contain branches to subroutines up to a certain level of complexity. The following example will illustrate this. To execute the program line x&=x&+(y&*y&-y&)/y&+z& fifty thousand times, a compiled program (without the loop commands) requires about 2.56 seconds. But this line can also be broken up into x&=x&+(y&*y&-y&)/y& x&=x&+z& These two lines perform the same task, from the point of view of the result, as the first statement. However, the compiled program requires only about 1.875 seconds for the execution of these lines. The rule that can be derived from this is: Break up lines containing more complicated integer calculations into several lines. To understand why the two-line variant executes faster than its one-line equivalent, we must analyze the corresponding section from the (symbolically) disassembled program. The line x&=x&+(y&*y&-y&)/y&+z& is translated into move.w -$7ffe(a5),d0 muls -$7ffe(a5),d0 ;y&*y& movea.w -$7ffe(a5),a0 sub.l a0,d0 ;-y& move.w -$7ffe(a5),d1 ext.l d1 bsr LDIV ;/y& movea.w -$8000(a5),a0 add.l a0,d0 ;+x& add.w -$7ffc(a5),d0 ;+z& move.w d0,-$8000(a5) The addresses of the variables once again depend on the order of their introduction into the program. Here, for example, the variable x& was introduced first, y& second, and z& third. Thus their addresses are x& -$8000(a5) y& -$7ffe(a5) z& -$7ffc(a5) In the listing you will find the line bsr LDIV, calling a subroutine for the division of two integer values. If you now compare this listing with the two-line version, you will find that the latter contains no subroutine call. The statements x&=x&+(y&*y&-y&)/y& x&=x&+z& produces the code: move.w -$7ffe(a5),d0 muls -$7ffe(a5),d0 ;y&*y& movea.w -$7ffe(a5),a0 sub.l a0,d0 ;-y& move.w -$7ffe(a5),d1 divs d1,d0 ;/y& add.w d0,-$8000(a5) ;End of first line move.w -$7ffc(a5),d0 add.w d0,-$8000(a5) ;+z& As you can see, this listing is a few instructions shorter than the previous one and contains no subroutine calls using bsr (branch subroutine). The code will become even more efficient, by the way, if you use reverse Polish notation with ADD x&,... instead of x&=x&+... In the interpreter, the one-line variant is faster than the two lines. But if you wish to tailor your programs to the compiler, you should present it with relatively short integer arithmetic statements only, which it will best be able to code into assembler instructions. Brackets are often inserted into calculations for reasons of clarity, although strictly speaking they are superfluous. Thus instead of x&=x&+(y&*y&-y&)/y& you could use the line x&=x&+((y&*y&)-y&)/y& We are not concerned here with the clarity of the example. You will find that in the interpreter, the version with the additionai pair of brackets is slower. In the compiled program, however, both versions are equally fast since the same code is generated from them. So if you want to insert brackets to improve intelligibility, you can do this without a speed penalty in the compiled program as long as the brackets have no influence on the result of the calculation.