+therealbountybob Posted June 29, 2010 Share Posted June 29, 2010 Still trying to eek out every little bit of performance for my new game 'Gwobby Strikes Back'. I have an if statement with two conditions e.g. 'IF FF=0 AND JC=0 THEN GOSUB etc.' Q1. Does it matter which way round the conditions go, if FF was the less likely to be true should this be first? Q2. How does this compare to IF FF+JC=0 THEN GOSUB etc (this saves me a few bytes in RAM) but is it the same processing time as above? Speed is more important to me. Q3. If I have three or more conditions does the method used in Q2 improve processing time? Q4. And a harder question: In places I'm also using the ON statement with a single condition instead of IF e.g. 'ON F0=0 goto 1050:more code:IF JJ=0 then goto 1090' (to effectively allow multiple IFs or additional code on the same line) is the ON statement slower to execute than an IF or does the performance gain from having less lines of code outweigh this? Thanks Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 29, 2010 Share Posted June 29, 2010 (edited) 1. I don't think the order would matter but it might be worth testing. 2. Adding them together would likely take longer than a compare. 3. More additions would probably take longer again. Each number has to be added in turn. 4. I think ON .. GOTO should be quicker in many cases. In theory Basic should just convert the test variable to 2-byte integer, then it can do a mega-quick compare and then GOTO whatever line is called. Avoiding branches will speed up a program, so try to have the GOTO occur on the rarer or less critical conditions. IF .. THEN can also be sped up lots if you just use pure logic conditions instead of comparisons. e.g. you have a variable FLAG which is 1 or 0. Instead of IF FLAG=1 THEN GOSUB 1000 use IF FLAG THEN GOSUB 1000 You can also use the NOT operator if you need to test zero value. IF NOT (A) THEN GOSUB 1000 should run quicker than IF A=0 THEN GOSUB 1000 Plus, doing stuff with logic rather than comparisons can save memory. Back to that first one, it'd should run quicker with IF NOT (FF AND JC) THEN ... Edited June 29, 2010 by Rybags Quote Link to comment Share on other sites More sharing options...
danwinslow Posted June 29, 2010 Share Posted June 29, 2010 I vaguely remember something about making sure that common goto/gosub targets be towards the beginning of the source code...to save line number lookup time, as it was sequentially searched from the beginning. Not sure if thats (still) true or not. Quote Link to comment Share on other sites More sharing options...
+David_P Posted June 30, 2010 Share Posted June 30, 2010 I vaguely remember something about making sure that common goto/gosub targets be towards the beginning of the source code...to save line number lookup time, as it was sequentially searched from the beginning. Not sure if thats (still) true or not. Yes, for Atari BASIC (not others) code at the beginning will run faster than code at the end, as each line number is looked up starting at the top of the program and working down. If you have space in the variable table, replacing constants with variables will speed things up. For example: The number "0" is treated as a floating point number every time it appears, taking 6 bytes of memory. Defining a variable, such as "Z=0" and replacing all the "0"s with "Z"s will reduce the program size and speed things up a little. Using logical operators will also speed things up - in the earlier example, "IF NOT (JC+FF) THEN GOSUB" is faster than either of the two examples given. Don't be afraid to use longer variable names - easier to debug in the future. The first apearance of a variable takes the name's length of characters. Every subsequent appearance uses one byte only, since Atari BASIC tokenizes your program. Look at old ANALOG and ANTIC magazines for ML routines to speed things up. Crib mercilessly from them. Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 30, 2010 Share Posted June 30, 2010 Near the start of the program is only faster for branches (GOTO/SUB, NEXT, RETURN etc) Constants take more memory but are actually a bit faster than using variables. The difference is small such that you should only use constants when it's critical. It's also faster and saves more RAM if you pack as many statements into each line as possible. Another big memory saver is to use strings instead of arrays if the numbers you're storing will be low. But you lose a bit of speed because in most cases you need to do the ASC/CHR conversion. Quote Link to comment Share on other sites More sharing options...
Crimefighter Posted June 30, 2010 Share Posted June 30, 2010 I've seen that using graphics characters instead of text characters also speeds things up. Quote Link to comment Share on other sites More sharing options...
+David_P Posted June 30, 2010 Share Posted June 30, 2010 Constants take more memory but are actually a bit faster than using variables. The difference is small such that you should only use constants when it's critical. Actually, no. Each appearance of a number costs you 6 bytes of memory. A constant will cost you one byte in the variable table, byte(s) for the constant name, six bytes for the data the constant. Overhead = 8 bytes total (assuming you use a single character for the name). Therefore, if a number appears more than once using a constant will save memory (since each use will be one byte plus overhead, versus six bytes for each appearance of a number). However, if your program is so large that that small number of bytes makes a difference you may want to re-think your design and go to a more modular program, or store some data in disk files to be loaded only as needed. If you're not using it for ML routines, page 6 is a great place to stash variables being shared between BASIC programs. So, for example, have a title screen program that collects some input (players, difficulty etc) and store that information on page 6. Then the main program is loaded, and recovers that information from Page 6. Quote Link to comment Share on other sites More sharing options...
Shawn Jefferson Posted June 30, 2010 Share Posted June 30, 2010 (edited) You could probably very easily test the performance of various comparisions using a long FOR NEXT loop... checking the system timers before and after. I just wrote a very quick and dirty test in BASIC, and the order of the comparisons didn't seem to have any effect on the speed (over 100 iterations), however using the NOT(FF+JC) notation definitely was faster as was mentioned. It saved about 10 jiffies over 100 iterations. Using JC+FF=0 was about 7 jiffies faster than the FF=0 AND JC=0 method. Edited June 30, 2010 by Shawn Jefferson Quote Link to comment Share on other sites More sharing options...
Rybags Posted June 30, 2010 Share Posted June 30, 2010 Constants take more memory but are actually a bit faster than using variables. The difference is small such that you should only use constants when it's critical. Actually, no. Each appearance of a number costs you 6 bytes of memory. A *constant will cost you one byte in the variable table, byte(s) for the *constant name, six bytes for the data the **constant. Overhead = 8 bytes total (assuming you use a single character for the name). Therefore, if a number appears more than once using a constant will save memory (since each use will be one byte plus overhead, versus six bytes for each appearance of a number). I think you've got them mixed up. In your text, * should be "variable", ** "variable data". That corrects your statement which in turn makes it agree with what I said anyway. Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted June 30, 2010 Author Share Posted June 30, 2010 You could probably very easily test the performance of various comparisions using a long FOR NEXT loop... checking the system timers before and after. I just wrote a very quick and dirty test in BASIC, and the order of the comparisons didn't seem to have any effect on the speed (over 100 iterations), however using the NOT(FF+JC) notation definitely was faster as was mentioned. It saved about 10 jiffies over 100 iterations. Using JC+FF=0 was about 7 jiffies faster than the FF=0 AND JC=0 method. I'm pretty much down to very fine tuning now, the previous help a few months ago (before playing His Dark Majesty interrupted things) sorted Page 6/Casbuf etc... I've optimised as much as possible used variables and turbo basic constants outside my main loop to save RAM and used literals in the main loop for speed. The ON/NOT combo seemed to help little Gwobby move a tad faster! I suppose where I have ON Q>0 GOTO... I could see if it will take ON NOT(Q) GOTO... I found a weird one where I had a nice formula using GOTO 1000+RAND(%2)*10 and I thought I'd be clever and add a level check for the third option GOTO 1000+(RAND(%2)+(LE>6))*10 but this made the random number stay at 0 if LE was less than 7 and stay at 1 where it was 7 or more... back to the IF Just spent another entire session trying to sort out my colour schemes; boy every game I swear I'm not going to do this Thanks for all the help guys p.s. Shawn can you post the code you used for the code timings, I did once mess around with using the timers but never really got anything meaningful to show up. Quote Link to comment Share on other sites More sharing options...
Shawn Jefferson Posted July 1, 2010 Share Posted July 1, 2010 It wasn't very elegant, just something like this: 10 ? PEEK(18), PEEK(19), PEEK(20) before and after the testing loop. Quote Link to comment Share on other sites More sharing options...
JamesD Posted July 1, 2010 Share Posted July 1, 2010 If you want to speed up a BASIC program, can't you just compile it? Quote Link to comment Share on other sites More sharing options...
+David_P Posted July 1, 2010 Share Posted July 1, 2010 I think you've got them mixed up. In your text, * should be "variable", ** "variable data". That corrects your statement which in turn makes it agree with what I said anyway. Remind me not to post early in the morning when I contradict myself. Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted July 2, 2010 Author Share Posted July 2, 2010 If you want to speed up a BASIC program, can't you just compile it? I'm using Turbo Basic but I have a two part game file and multiple font files etc Quote Link to comment Share on other sites More sharing options...
Roydea6 Posted July 3, 2010 Share Posted July 3, 2010 I'm using Turbo Basic but I have a two part game file and multiple font files etc I use Turbobasic occasionally also, and wondering about optimizing. Which would be best to use: SIZE=ASC(B$(3,3))+256*ASC(B$(4,4)) or SIZE=DPEEK(ADR(B$(3,3))) Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 3, 2010 Share Posted July 3, 2010 Second one would not only save RAM but probably be a good deal quicker. But, when using ASC( or ADR( you should be able to get away with only specifiying the start character, e.g. SIZE=ASC(B$(3))+256*ASC(B$(4)) Quote Link to comment Share on other sites More sharing options...
+David_P Posted July 5, 2010 Share Posted July 5, 2010 And here's an ANTIC article on a number of tricks to speed up and shrink BASIC programs. http://www.atarimagazines.com/v9n2/basicspeedups.html Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted July 5, 2010 Author Share Posted July 5, 2010 Here's me reporting back: I used the timers and a few statments in regular BASIC first, these were the quickest variations: IF NOT (E AND F) (rather than IF E=0 AND F=0 or IF E+F=0) ON NOT E (instead of ON E=0) Using the IF's on separate lines was quicker than using ON to get them onto the same line, but using ON to have less lines of code improves the speed of routines further down the program, and makes the code darn messy!) Along with all the tips here and merging a 2nd subroutine into my main loop my game works noticably faster now so thanks again guys Quote Link to comment Share on other sites More sharing options...
Rybags Posted July 5, 2010 Share Posted July 5, 2010 You can also use expressions in GOTO but it can get a bit messy. e.g. you have a Boolean (0 or 1) variable that normally gets tested, so you could replace: 1000 IF A=1 THEN GOTO 1100 1020 REM Case A=0 stuff here 1100 REM Case A=1 stuff here with: 1000 GOTO 1010+A 1010 REM Case A=0 stuff here 1011 REM Case A=1 stuff here Not sure if that's going to save a lot of time though. Quote Link to comment Share on other sites More sharing options...
+David_P Posted July 6, 2010 Share Posted July 6, 2010 You can also use expressions in GOTO but it can get a bit messy. e.g. you have a Boolean (0 or 1) variable that normally gets tested, so you could replace: 1000 IF A=1 THEN GOTO 1100 1020 REM Case A=0 stuff here 1100 REM Case A=1 stuff here with: 1000 GOTO 1010+A 1010 REM Case A=0 stuff here 1011 REM Case A=1 stuff here Not sure if that's going to save a lot of time though. It also introduces trouble - the minute A is greater than 1. Bounds checking (or at least bounds limiting) is very important when using variables to control branching. Quote Link to comment Share on other sites More sharing options...
+therealbountybob Posted July 20, 2010 Author Share Posted July 20, 2010 (Have used the ON with expression to select screen level data ) I found another couple of turbo basic functions DIV and MOD... used 'LE DIV 12' instead of 'INT(LE/12)' this saves 3 bytes (didn't check if was quicker as not in my main loop). Quote Link to comment Share on other sites More sharing options...
Irgendwer Posted July 26, 2010 Share Posted July 26, 2010 (edited) ... Each appearance of a number costs you 6 bytes of memory. ... Since he works in Turbo-Basic he could also use: %0 %1 %2 %3 since these are defined there as "short and quick"-constants without using the var.-table. Example: 1020 I=I+%1:IF I=%3 THEN CLOSE #%2:GO# MAIN Edit: BTW: A replacement of "ON GOSUB" with "ON EXEC" is normally also smaller and faster (and better readable). Edit2: The movement of subroutines to the beginning of the program brings no benefit in Turbo-Basic. Edited July 26, 2010 by Irgendwer Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted August 7, 2010 Share Posted August 7, 2010 yeah... turbo basic is already optimised... and you easily can do bit logic operations which are not good in standard basic. in TB you can use TIME$ I guess to get the system timing or you do a print dpeek(18)+peek(20)*65536 Quote Link to comment Share on other sites More sharing options...
Heaven/TQA Posted August 7, 2010 Share Posted August 7, 2010 in TB i never used any line numbers for jumps and conditions? always label jumps and procedures... but are these quicker? Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted August 7, 2010 Share Posted August 7, 2010 Only trouble with TB, IIRC, was the 256 variable limit. With many labels and PROCs, I used to hit the limit quite often. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.