nathanielbabiak 2020-12-04 21:50 (Edited)
Caution! Syntactic (within-same-line) speed optimizations are discussed frequently on this console. But, there's a 99% chance algorithmic (not syntactic) improvements will provide an order-of-magnitude speed improvement vs. doing any of these! These are only recommended for use within raster interrupts (not even VBL interrupts require them).
Non-zero values (int and float) evaluate to true, these are smaller and faster, for example with 12.34
(or any variable replacing 12.34
):
IF X<>0 THEN
with IF X THEN
IF X<>0 AND Y<>0 THEN
with IF X*Y THEN
IF X=0 OR Y=0 THEN
with IF X*Y=0 THEN
IF X < 0 OR X>= 12.34 THEN
with IF INT(X/12.34) THEN
IF X>= 0 AND X< 12.34 THEN
with IF INT(X/12.34)=0 THEN
There's two non-zero evaluation tricks if you're sure X
and Y
will always have matching signs:
IF X<>0 OR Y<>0 THEN
with IF X+Y THEN
IF X=0 AND Y=0 THEN
with IF X+Y=0 THEN
There's a few more non-zero evaluation tricks when X
and, for example 1234
(or any variable replacing 1234
), are integers:
IF (X AND %001)=%001 THEN
with IF X AND %001 THEN
IF (X AND %010)=%010 THEN
with IF X AND %010 THEN
IF (X AND %100)=%100 THEN
with IF X AND %100 THEN
IF X<=-1234 OR X>=1234 THEN
with IF X\1234 THEN
IF X> -1234 AND X<1234 THEN
with IF X\1234=0 THEN
You can store evaluations per-raster-line in an array to save a single clock cycle:
IF RASTER=64 THEN
with IF LOOKUP(RASTER) THEN
(after running DIM GLOBAL LOOKUP(127)
and LOOKUP(64)=1
elsewhere in your code)If you're only performing one instruction occasionally per-raster-line, note that some instructions perform a graceful exit when executed with unrealistic arguments (for example COPY SRC, 0 TO DST
), so the above tip can be shortened further (depending on the number of nonzero LOOKUP()
entries and your specific instruction):
IF LOOKUP(RASTER) THEN COPY SRC, 40 TO DST
with COPY SRC, LOOKUP(RASTER) TO DST
(after initializing the values of the LOOKUP()
array elsewhere in your code)If you're performing various raster tricks on continuous sequences of RASTER
scanlines, don't use either switch-case
structure described below (they're too slow), instead change raster subprograms within the raster interrupt itself. Try this:
SUB RASTER1 \\ [first trick, upper screen] \\ IF LOOKUP(RASTER) THEN ON RASTER CALL RASTER2 \\ END SUB
SUB RASTER2 \\ [second trick, middle screen] \\ IF LOOKUP(RASTER) THEN ON RASTER CALL RASTER3 \\ END SUB
SUB RASTER3 \\ [third trick, bottom screen] \\ END SUB
ON VBL CALL RASTER_RESET
SUB RASTER_RESET \\ ON RASTER CALL RASTER1 \\ END SUB
This switch-case
structure requires few tokens, but it's slow:
IF X=0 THEN
CALL X0
ELSE IF X=1 THEN
CALL X1
ELSE IF X=2 THEN
CALL X2
ELSE IF X=3 THEN
CALL X3
ELSE IF X=4 THEN
CALL X4
ELSE IF X=5 THEN
CALL X5
ELSE IF X=6 THEN
CALL X6
ELSE IF X=7 THEN
CALL X7
END IF
This switch-case
structure is much faster, but requires more tokens:
IF X<4 THEN
IF X<2 THEN
IF X<1 THEN CALL X0 ELSE CALL X1
ELSE
IF X<3 THEN CALL X2 ELSE CALL X3
END IF
ELSE
IF X<6 THEN
IF X<5 THEN CALL X4 ELSE CALL X5
ELSE
IF X<7 THEN CALL X6 ELSE CALL X7
END IF
END IF
In small projects, using GOTO
can be much easier to read than avoiding it, but it's harder to maintain nonlooped code, so avoid GOTO
in large projects. In the vast majority of instances you think you need it, the algorithm isn't coherent.
There's one instance where GOTO
is common: implementing the C keywords continue[(n)]
and break[(n)]
.
If an algorithm needs more than 3 new variable names, this is smaller than declaring one variable per-line. It's slower only because of overhead, otherwise the same speed O(n).
DECLARE:
DATA 0, 0, 0, 0, 0, 0, 0, 0
LOAD DECLARE
READ Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7
Single-command if-then statements are smaller (and sometimes faster too) when written on a single line like this:
IF TEST1 THEN CALL FOO
IF TEST1 THEN CALL FOO ELSE CALL BAR
IF TEST1 THEN CALL FOO ELSE IF TEST2 THEN CALL BAR ELSE CALL ZOT
This loop is small but slow:
FOR X=0 TO 7
TEXT 0,X,"-"
NEXT X
This unrolled loop is fast but large:
TEXT 0,0,"-"
TEXT 0,1,"-"
TEXT 0,2,"-"
TEXT 0,3,"-"
TEXT 0,4,"-"
TEXT 0,5,"-"
TEXT 0,6,"-"
TEXT 0,7,"-"
X = ASC( CHR$( X ) )
will convert an 8-bit value from unsigned to signed.DATA
commands, containing strings of hex-values, use VAL("0X"+VALUE$)
to retrieve up to three bytes at a time.LowRes NX supports a limited format for short-circuit evaluations. If you have evaluations A
, B
, and C
, you can replace:
IF A AND B AND C THEN CALL ALL_TRUE ELSE CALL SOME_FALSE
With:
IF A THEN IF B THEN IF C THEN CALL ALL_TRUE ELSE CALL SOME_FALSE
moechofe 2020-12-05 07:29
good stuff
nathanielbabiak 2022-06-30 01:30
Thanks moechofe!
nathanielbabiak 2022-06-30 01:30
Many changes over the past two years - this update covers all the nuance I've learned pushing the system to its limits!
Hope it helps anybody who sees this!