Jun-11 7:17 PM - Jun-11 9:50 PM
Initially, I described some speculative causes for 'slowness':
- a cursory desk-check of the code showed that the implementation was parsing plaintext BASIC for each line each time it was executed. This isn't 'wrong', but I know that BASIC's back in the day (70s-80s) typically used 'tokenization' to save space and parsing effort at runtime. I.e., at program entry time, for each line submitted, it was parsed for keywords, and they were replaced with a single byte representing that keyword. This avoided re-parsing at runtime, and saved space. Maybe tokenization was worth the effort? That would involve significant work, though (in my opinion).
- similarly, line numbers were stored as text along with their associated code. BASICs back in the day often stored line numbers as binary in a little 'header', and also often had a forward pointer to the next line. This allowed skipping about through the program to happen quicker.
- I also mentioned that all of this was CPU bound, but screen I/O (and any other I/O) might be worth considering. In my TRS-80 project, I initially reused some existing code for doing the video, including font support. For whatever reason, that code stored fonts in column-major order, whereas row-major was much more natural for the underlying hardware implementation. When I had re-generated the font to be row-major (and also with an endianess that matched the SPI ordering), then I was able to blit rows of pixels at a time, instead of setting them dot-by-dot (and with the added overhead of function calls). This dramatically increased performance for my project.
I asked what does 'slow' mean in this context, because there really was no baseline: it was a bespoke project unlike any other. It just 'felt' slow at some intuitive level. I asked if I could have a sample BASIC program that felt slow, and that I would take a looky-loo.
The sample program happened to be an implementation of Conway's game of Life, and I was familiar with that. They were super popular in the 70s-80s, and I had run one at least once on my actual TRS-80 back in the day, with it's screaming hot ~1.77 MHz Z-80. And Z-80's took 4-23 clocks to do one instruction, so I would think that, yeah, a 48 MHz MIPS could probably do a little better.
Now, I had no reason to believe that the video thing I mentioned was relevant here, but I did want to point out that sometimes it's not where you think it is. In that case, you could 'optimize' the BASIC until it took zero CPU time, and that still would not get you improvements to deal with an I/O bound bottleneck, or even a CPU bottleneck that is not where you are looking. Believe me, I have made this mistake before.
Speculation is useful as a heuristic to formulate hypotheses, but you really need to test empirically. Not measuring risks wasting development time chasing wild aquatic fowl, and that is itself a kind of speed optimization.