Qbasic, let's face it, is a slow language. But there are 15 little often unknown tricks that can help speed your programs up
1) Qbasic reads integers much faster than any other type of variable (because they are only 2 bytes), so use then whenever possible. Qbasic also automatically converts longer variables to integers, so don't use the INT command, it just takes up time.
FROM: FOR b = 0 TO 1 STEP .1 a% = INT(a) NEXT
TO: FOR b% = 0 TO 10 a% = b% / 10 NEXT
2) Use direct access commands (INP, OUT, PEEK, and POKE) whenever possible. Use INP(96) instead of INKEY$, and OUT &h3c9 instead of PALETTE, PEEK instead of POINT and POKE instead of PSET
FROM: SCREEN 13 FOR x% = 1 TO 100 FOR y% = 1 TO 100 PSET (x%, y%), POINT (x%, y%) + 1 NEXT NEXT DO: LOOP UNTIL INKEY$ " "
TO: SCREEN 13 DEF SEG = &HA000 FOR y% = 1 TO 100 y2% = y% * 320 FOR x% = 1 TO 100 POKE (y2% + x%), PEEK (y2% + x%) + 1 NEXT NEXT DEF SEG DO: LOOP UNTIL INP(96) = 57
3) Store the results of complicated algebra and trig in arrays
FROM: FOR a% = 1 to 360 a = a% * 180 / 3.1415926535 x = COS(a) * 100 + 100 y = SIN(a) * 100 + 100 PSET (x,y),10 NEXT
TO: DIM circlex%(360), circley%(360) FOR a% = 1 TO 360 a = a% * 180 / 3.1415926535 circlex%(a%) = COS(a) * 100 + 100 circley%(a%) = SIN(a) * 100 + 100 NEXT ... FOR a% = 1 to 360 PSET (circlex%(a%), circley%(a%)),10 NEXT
4) If you have two or more FOR-NEXT loops, make all the calculations for one loop outside of the others, tough to understand, the example is pretty explainatory.
FROM: FOR a% = 1 TO 10 FOR x% = 1 TO 10 aa% = sin(a%) * a% ^ 3 + x * 2 NEXT NEXT
TO: FOR a% = 1 To 10 suba% = sin(a%) * a% ^ 3 FOR x% = 1 TO 10 aa% = suba% + x * 2 NEXT NEXT
5) If a variable doesn't change, make it CONST
6) Use FOR-NEXT instead of DO-LOOP or WHILE-WEND: Qbasic moves much faster because it have to read less code. Instead of 3 line (DO, calculation, LOOP) it only reads 2 (FOR and NEXT) making it 3/2 the speed
FROM: DO a% = a% + 1 LOOP UNTIL a% = 12345 WHILE b% < 98765 b% = b% + 1 WEND
TO: FOR a% = 1 TO 12345:NEXT FOR b% = 1 TO 98765:NEXT
7) People think making their code as short as possible increases speed - it does, but you have to make it shorter for the computer, not the user, heres what i mean. In a FOR-NEXT loop every time it loops it read 3 commands (FOR, command, NEXT), minimize that
FROM: FOR a% = 10 to 20 PSET (15,a%), 14 NEXT 'The computer reads 33 commands
8) Only use FOR-NEXT if you are running out of memory or the loop is extremely long, even then break it down
FROM: FOR a% = 1 to 500 PSET (a%,10), 14 NEXT 'The computer reads 1500 commands
TO: FOR a% = 1 to 500 STEP 5 PSET (a%,10), 14 PSET (a% + 1,10), 14 PSET (a% + 2,10), 14 PSET (a% + 3,10), 14 PSET (a% + 4,10), 14 NEXT 'The computer reads 700 commands
9) Qbasic stores 2D arrays in x variables across and y variables down, and the x's are in a scanline so read then from the scanline, rather than making qbasic jump around the RAM
FROM: DIM array%(100,100) FOR x% = 1 TO 100 FOR y% = 1 TO 100 PSET (x%,y%), array%(x%,y%) NEXT NEXT
TO: DIM array%(100,100) FOR y% = 1 TO 100 FOR x% = 1 TO 100 PSET (x%,y%), array%(x%,y%) NEXT NEXT
10) Use 1D arrays rather than 2D use DIM array%(10000) rather than array%(100,100)
11) Use BLOAD / BSAVE files instead of long loops of GET and PUT
12) Use SELECT CASE instead of IF-ELSEIF-END IF
13) Never compare against zero
FROM: IF a% <> 0 THEN PRINT "a% <> 0"
TO: IF a% THEN PRINT "a% <> 0"
14) Compile it. Qbasic emulates the .bas files into another language that DOS must then emulate, if DOS emulates its directly it speeds the program up dramatically
15) Multiplication is up to five or six times faster than using powers. Use them to dramitically speed up programs with lots of powers.
FROM: a = b ^ 4
TO: a = b * b * b * b
16) If you have a multiplication calculation that you do over and over again, such as 320 * y + x for an offscreen buffer, convert it to asm. Assembly has a bit shifting command, that eliminates multiplication, which is much slower.
FROM: DEF SEG = VARSEG(buffer%(0)) POKE VARPTR(buffer%(320 * y% + x% + 2)), c% ... PUT (0,0), buffer%, PSET
TO: CALL plotpixil(BYVAL(x%), BYVAL(y%), BYVAL(c%)) ... CALL copybuffer(BYVAL(buffer%(0)), BYVAL(A000))
;in library .model medium, basic .stack 200h .386 .code public buffercopy, plotpixel buffercopy proc push ds push bp mov bp, sp mov ds, [bp+10] mov es, [bp+8] xor si, si xor di, di mov cx, 32000 rep movsw pop bp pop ds ret 4 buffercopy endp plotpixel proc push bp mov bp, sp mov es, [bp+12] mov dx, [bp+8] mov bx, dx shl dx, 8 shl bx, 6 add dx, bx add dx, [bp+10] mov di, dx mov al, [bp+6] mov es:[di], al pop bp ret 8 plotpixel endp end