====== Performance tips ====== You can follow a couple of good practices to speed up your **XC=BASIC** programs. ==== Tip #1: Use the right type ==== While floats allow a much wider range of values, it's way much slower to operate on them. Always use integers if you don't need the precision of floats. Bytes are even faster, but offer a very small numeric range. Use them if you are sure that the value will always range between 0 and 255. ==== Tip #2: Use FAST variables ==== Since version 2.1, some variables can be placed on the zeropage for faster load/store operations. See [[dim|DIM]] for details. ==== Tip #3: Do arithmetic only when necessary ==== Even the simplest addition or subtraction can take precious time, especially when used in loops. Make sure to eliminate all the arithmetic operations that are not necessary in runtime. Wrong example: rem ** draw a line on the bottom of the screen ** const SCREEN = 1024 for i! = 0 to 39 poke SCREEN + 40 * 24 + i!, 99 next i! Notice that the expression ''SCREEN + 40 * 24'' is evaluated in every iteration although the result is always the same. You should rather do the math yourself: rem ** draw a line on the bottom of the screen ** const BOTTOM_LINE_START = 1984 for i! = 0 to 39 poke BOTTOM_LINE_START + i!, 99 next i! Note: you may say that the compiler should be smart enough to recognize operations on constant values and evaluate them in compile time - and you'd be right. Maybe this kind of optimization will be implemented in a later version. ==== Tip #4: Use constants ==== Unlike variables, constants do not need to be accessed from memory when they're being evaluated therefore they're evaluated much faster. ==== Tip #5: Use INC and DEC ==== Using inc a instead of a = a + 1 is considerably faster. ==== Tip #6: Provoke fast array operations if possible ==== If the compiler detects that the array subscript of a byte type array is also a byte type, it will exploit the processor's fast indexed store and lookup operations, resulting to a much higher speed. Examples: rem -- this is SLOW dim x![100] index = 50 print x![index] rem -- this is FAST dim x![100] index! = 50 print x![index!] ==== Tip #7: use ON for branching ==== An ''ON ... GOTO'' or ''ON ... GOSUB'' construct is faster than its ''IF ... THEN GOTO/GOSUB'' equivalent. It's especially useful when branching on a TRUE/FALSE condition, for example: rem -- branching using IF ... THEN rem -- assume x! is a zero or one (TRUE/FALSE) value if x! = 0 then goto false_case else goto true_case rem -- same as above but FASTER on x! goto false_case, true_case ==== Tip #8 REPEAT ... UNTIL is faster than FOR ... NEXT ==== You can gain some speed boost using ''REPEAT ... UNTIL'' instead of ''FOR ... NEXT'': for i!=0 to 99 next i! Equivalent but faster: i! = 0 repeat inc i! until i! = 100 ==== Tip #9: Use LSHIFT() and RSHIFT() ==== It's much faster to multiply or divide by powers of two using bit shifting operations. Use [[lshift|LSHIFT()]] and [[rshift|RSHIFT()]] whenever you can. ==== Tip #10: Know the optimizer ==== **XC=BASIC** features a built-in optimizer that replaces commonly used program sequences with faster opcode sequences. To make good use of the optimizer, bear in mind the following program structures that can be optimized: * Value assignment of bytes and integers * Addition of bytes and integers * Subtraction of bytes and integers * Comparison of bytes, e. g. ''IF x! > 5 THEN ...'' * ''IF'', ''WHILE'' and ''UNTIL'' statements with byte type comparison as condition, e .g ''WHILE x! <= 255'' * Array access of byte type arrays with byte type index * Bitwise operators on bytes * POKE and PEEK (they're the fastest when using constant addresses) The following are not optimized at all: * Operations on floating point types * I/O commands like ''PRINT'', etc. * Convenience commands like ''TEXTAT''