Optimizing your TI-92 programs

Have you ever wanted to know how to make your programs just a tinny bit faster? I mean your program is almost fast enough to be fun, but something is holding it back? If you answer yes to either of these questions then this tutorial is for you.

Here are the programs I tested:


Program using 'If' statements

asf()
Prgm
Local a,b
{10,-1}->b
Pause "start"
For a,1,100
b[mod(a,2)+1]->xc
b[mod(a,2)+1]->yc
if xc<0:0->xc
if xc>10:10->xc
if yc<0:0->yc
if yc>10:10->yc
EndFor
Disp "done"
EndPrgm


Program using 'When' statements

 asd()
Prgm
Local a,b
{10,-1}->b
Pause "start"
For a,1,100
b[mod(a,2)+1]->xc
b[mod(a,2)+1]->yc
when(xc<0,0,when(xc>10,10,xc))->xc
when(yc<0,0,when(yc>10,10,yc))->yc
EndFor
Disp "done"
EndPrgm

Which of the programs do you think was smaller?

Which was faster?

CharactersAfter TokenizationTime to executeCycles per second
Using If commands180179 bytes9.48 Seconds10.5485
Using When commands190165 bytes8.48 Seconds11.7924

As you can see, the When command won by a full second and used 14 less bytes when tokenized.

So what is this magic tokenization?

Tokenizing is where before the calculator can use a basic program it must interpret the lines so as to be able to run faster. This is the reason after editing a program there is a small (or large) pause before the program can run. This is also why the calculator can tell you right away that there is a syntax error. During tokenization, the calculator changes most (not all) keywords into a byte or two, depending on what it is, and this is why even though the When program takes up 10 more characters, after tokenization it takes up 14 less. Remember returns and colons take up a byte each, and variable names are not tokenized.

So, why is this faster?

If you look at the code, you will notice that the when command inside the when command is only called when the first test is false. So, does the storing take up more time, for every time you are doing that? Yes, the storing does take up extra time. However, to store into a variable takes about .0105 seconds. This time does add up, but doing two extra comparisons every other time and phrasing the two other lines every time takes up an extra second ever 100 iterations.

Big deal, 100 times is a lot of iterations.

If you are so sure, then type in both programs and tell me which one you would rather have in a program that you use everyday. I bet you would rather run a program that is about 11.792% faster than the other one. How many times might a game use this? A lot.

So, how do I use this in my program?

I would suggest that when you have a bounds checking routine instead of using this:

if xc<0:0→xc
if xc>10:10→xc
if yc<0:0→yc
if yc>10:10→yc

Use:

when(xc<0,0,when(xc>10,10,xc))→xc
when(yc<0,0,when(yc>10,10,yc))→yc

The lesson is not just use when's where you can instead of if's, but it is to time your routines and discover what is slow and then try ways to get around it, such as using when's. Remember to look in the manual and find commands that are close to what you want so you can get them done faster, because sure it's fun to write you own sorting algorithm, instead of using SortA or SortD. But who is going to want to use your program or game if someone else has one that is twice as fast, or half as big?

Lots of Routine Times
500 iterationsSizeSeconds to execute
For78 bytes5.10 seconds
While90 bytes8.71 seconds
Loop100 bytes9.44 seconds
Goto94 bytes10.75 seconds
100 iterationsSeconds to Execute
Indirection to an array (using a mod)3.32 Seconds
Direct to an array (using a mod)3.00 seconds
Indirection to an array (single spot)2.83 Seconds
Direct to an array (single spot)2.46 seconds
Indirection to a variable3.26 seconds
Direct to a variable2.80 seconds
50 iterationssizeSeconds to execute
If...Then...Else (True and False actions)138 bytes2.67 seconds
2 If...Then commands (True and False actions)147 bytes3.08 seconds
4 if commands (true and false actions)157 bytes3.80 seconds
If...Then (Only a true action)116 bytes1.32 seconds
2 If commands (Only a true action)121 bytes1.66 seconds
When commands (Only a true action)121 bytes3.01 seconds
100 iterationsSeconds to execute
Left (first 5 chars of a 10 char string)2.45 seconds
Right (last 5 chars of a 10 char string)2.45 seconds
Mid as a left2.53 seconds
Mid as a right2.45 seconds
Unoptimized mid as a right2.53 seconds
100 stores1.05 seconds.0105 seconds a store

I hope that these benchmarks will assist you in writing the fastest game or program possible in BASIC. A few more tips and I'll be done.

Never use goto's if you can help it. One, it is slow. Two, if you leap out of a control structure you waste memory in the stack, which means that exit, cycle and other commands will not work correctly (unless that is what you want :) and when stack space is wasted all other commands slow down so overall making your program slower, plus eventually when the stack space is filled and you'll get a memory error or maybe even a crash. Goto's have their place and their place is only where loop's, while's and for's will not work.

Space is important on a calc that has a limited amount memory. If your program needs large fancy graphics or small icons you must keep the size to a minimum. Try out Vector Man if you need full screen graphics. You just draw the graphics you want in Vector Man and it will spit out programs that draw it for you. Definitely try Icon Maker for tiles in a game as it makes them quickly and easily. Okay enough plugging for my programs. What I mean is if you need or want full screen graphics use the drawing commands as they often save space, which is at a premium. When using pictures use several if the picture is showing a logo, a lot of blank space, and some icons. It will save space, maybe 500-600 bytes, and often a little space is all the user wants when your program is deleted.

Copyright 1998 Michael Van Der Kolk