There is a lot of interest in how to make Petit Computer programs run faster, so this page is for a collection of optimizations.
Note that generally, optimizations are very bad for readability. Putting too much emphasis on optimization is a common beginners' mistake, because the benefits of readability are not as apparent or compelling until one has had more programming experience. Readability is important for maintainance (if a new bug is discovered, it will help greatly in locating the source(s) of the bug and fixing it without breaking something else), for expandability (if a new feature is to be added, readability makes it much easier to figure out how and where to add it), and for robustness (any kind of tinkering with highly-optimized code is more likely to cause a bug that's more difficult to diagnose and fix). The optimizations below will generally give an improvement of only a few percent at best. As a contribution to the programming community, readability is much more valuable than a few percent speed gain. But, since many contributions are not for the programming community to analyze and learn from, but instead are for the game-playing community to play, there is value in having a list of optimizations for use when the design is finalized and the bugs are fixed and the author doesn't care if others want to learn from or tinker with the code.
One final caveat: Petit Computer is a sophisticated piece of software. It has many subsystems, with many interactions between them, some quite subtle. There may be conditions where some of the tips mentioned below do not improve running speed, they may indeed slow things down.
Now for the actual list of optimizations (unless otherwise noted, these optimizations have only been observed on a 3DS running SmileBasic V2):
GOSUBtakes time. Copies of the code in-line will run faster.
FORloops take time. If a section of code is to be repeated a fixed number of times, copying the code will run faster than looping the code.
NEXTis faster if it does not have a variable name.
- If the branches of an
IFcommand are executed with 50/50 probability, it is faster overall to have the shorter branch beTHENand the longer branch beELSE; if the branches take an equal amount of time, it is faster to have the more commonly executed branch beTHENand the less commonly executed branch beELSE.
- Blank lines take time, comments take more time, and longer comments take yet more time.
- Removing unneeded spaces speeds things up (e.g. instead of
FOR I=0 TO 10, useFOR I=0TO 10).
- Having commands on successive lines is faster than using
:, the command separator, but faster yet is having commands follow one another without a command separator (e.g.A=B PRINT AorA=0B=0).
- Remove leading '
0's from integer literals (e.g. instead ofH=100T=010U=001, useH=100T=10U=1).
- Shorter variable names are faster.
- Shorter labels are faster.
- Accessing a scalar variable is faster than accessing an array entry. If a particular array entry occurs in many expressions, the time it takes to copy it to a scalar variable may be more than made up for by the speed increase in the following references to the value.
X*Xis faster thanPOW(X,2). However, ifXis replaced with a complicated expression that takes more time to evaluate, having it appear once in withPOWmay be faster than having it appear twice with multiplication.
- An integer numerical literal is faster without a decimal point following it, and a numerical literal without a decimal point is faster than reading a numerical variable.
- If you need a string representation of an integer numerical value, and you're not particular about the details of that representation,
HEX$is faster thanSTR$. Indexing a string array is faster than both (though this is subject to both the string memory limitation and the array memory limitation).
- When you need to
GOTOorGOSUBa label that depends on the value of a variable, it is quicker to use theON ... GOTOandON ... GOSUBcommands rather than useGOTOorGOSUBwith a string array.
- Using the empty string literal (
"") is faster than referencing a string variable that contains the empty string.
- A
FORthat takes the same number of iterations without aSTEPis faster than one with aSTEP(e.g.FOR A=1TO 10is faster thanFOR A=10TO 100STEP 10), and a positiveSTEPvalue is faster than a negativeSTEPvalue (e.g.FOR A=10TO 100STEP 10is faster thanFOR A=100TO 10STEP-10).
- The expression after
TOand the expression afterSTEPare evaluated each loop of theFOR. So, for example, consider the difference betweenFOR I=1 TO 100andFOR I=1 TO 10*10. The expression10*10takes more time than the expression100... and the secondFORtakes more time than the first, by one hundred times that much.
- Having
PNLTYPE "OFF"will speed up code. Except, it seems, under certain conditions where sprites are used, andWAITand/orVSYNCare used.
- The quote character (
") to close a string literal is optional if it is at the end of a line: surprisingly, it is faster to include the final quote than it is to omit it.
- Where you have
IF (condition1) AND (condition2) THEN..., it can sometimes be faster to haveIF (condition1) THEN IF (condition2) THEN.... Note that this is not always faster, sometimes it is slower; it is most effective whencondition1is rarely true, and/orcondition2takes a long time to compute. Also note that if there areELSEbranches, care will need to be taken, and this may makeANDthe faster option.
IF condition GOTO@labelis generally faster thanIF condition THEN@label, and both are faster thanIF condition THEN GOTO@label.
!before a value is faster than!=0after it.!!before a value is faster than==0after it. Note that!has a higher precedence than!=and==, so extra parentheses may be necessary, which then make the expression slower.
- Rearranging expressions may give a very slight speed-up. In general, it seems if you put the higher-precedence operators first, the expression will get evaluated a tiny bit faster.
- Finally, it is worth noting that
?is not faster thanPRINT. Apparently, the code gets tokenized before it gets run.