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. The examples below are smaller and faster, for example with 12.34 (or any variable replacing 12.34):
IF X<>0 THEN with IF X THENIF X<>0 AND Y<>0 THEN with IF X*Y THENIF X=0 OR Y=0 THEN with IF X*Y=0 THENIF X < 0 OR X>= 12.34 THEN with IF INT(X/12.34) THENIF X>= 0 AND X< 12.34 THEN with IF INT(X/12.34)=0 THENThere'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 THENIF X=0 AND Y=0 THEN with IF X+Y=0 THENThere'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 THENIF (X AND %010)=%010 THEN with IF X AND %010 THENIF (X AND %100)=%100 THEN with IF X AND %100 THENIF X<=-1234 OR X>=1234 THEN with IF X\1234 THENIF X> -1234 AND X<1234 THEN with IF X\1234=0 THENYou 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 SUBSUB RASTER2 \\ [second trick, middle screen] \\ IF LOOKUP(RASTER) THEN ON RASTER CALL RASTER3 \\ END SUBSUB RASTER3 \\ [third trick, bottom screen] \\ END SUBON VBL CALL RASTER_RESETSUB RASTER_RESET \\ ON RASTER CALL RASTER1 \\ END SUBThis 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 FOOIF TEST1 THEN CALL FOO ELSE CALL BARIF TEST1 THEN CALL FOO ELSE IF TEST2 THEN CALL BAR ELSE CALL ZOTThis 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,"-"
LowRes NX supports a limited format for short-circuit evaluations. If you have evaluations A, B, and C..., where brackets [...] indicate an optional parameter:
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]
Replace: IF A OR B OR C THEN CALL SOME_TRUE [ELSE CALL ALL_FALSE]
With: IF A THEN CALL SOME_TRUE ELSE IF B THEN CALL SOME_TRUE ELSE IF C THEN CALL SOME_TRUE [ELSE CALL ALL_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!
nathanielbabiak 2024-09-17 04:54
Four years in and I've finally added something (logical-or to the short-circuit evalulation section).