+OLD CS1 Posted August 1, 2020 Share Posted August 1, 2020 For years I have been programming TI BASIC with the same approach I use on the Commodore 64: subroutines go in low line numbers with the expectation that low line numbers are found more quickly during a GOSUB. However, in TI BASIC, both the statement table and line number tables build downward in VDP memory. While I have known this for years, I actually saw it in detail just a couple of days ago which makes it all-so-real as seeing is believing. Now I am left wondering if this approach is actually detrimental to execution speed as low line numbers are at the top of the table. I assume line numbers are searched from bottom to top as doing so means taking advantage of the VDP's automatic address pointer increment. Thus my question: what is the impact on speed when subroutines are at the top of the line number table (low line number) versus at the bottom (high line number.) Quote Link to comment Share on other sites More sharing options...
kl99 Posted August 1, 2020 Share Posted August 1, 2020 when I added TI Basic decoding support to Web99 it was interesting to see, that the ordering of the lines in memory is reflecting the order you entered them in the Basic Interpreter. So if you enter Line 200 before Line 100, then Line 150, you will never have that sorted in memory, not even when storing to tape or disk as the SAVE command does a memory dump program image. So if you do experiments, please consider entering the lines either ascending or descending to have no impact of a not sorted Program or LineTable in your test results. I suggest Classic99 for testing as it allows clipboard input and you can sort the programs to your needs for each testcase outside on the PC. 1 Quote Link to comment Share on other sites More sharing options...
ralphb Posted August 1, 2020 Share Posted August 1, 2020 Yes, Klaus, but the line number table is sorted, and I would guess that for every access to a statement, the number table is consulted. Anyway, that table is sorted "in numerically order from top to bottom", according to Thierry. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted August 1, 2020 Share Posted August 1, 2020 Do you want to see the source code of XB in GPL on how it saves or loads program just look at the source in RXB 2001 to RXB 2015E as every version has the source there in package. 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 1, 2020 Author Share Posted August 1, 2020 TIdBiT makes it easy enough to move subroutines around at whim for testing. What I would like is to not re-invent the wheel. I would suspect at some point or another, someone smarter than me took notice and did up the work to determine any penalties for putting subroutines in lower line numbers, thus nearer the top of the table, assuming the top of the table is the end of the search and not the beginning. 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 1, 2020 Author Share Posted August 1, 2020 This is not what I was expecting, on a couple of levels. I made two copies of my Tiles game in TI BASIC: TILES_1 with the subroutines at the front of the program (low line numbers, nearer to the top of the line number table,) and TILES_2 with the subroutines at the end of the program (higher line numbers, nearer to the bottom of the line number table.) I loaded TILES_1 and TILES_2 into two parallel instances of Classic99. I ran them both at the closest possible time I could muster by hitting ENTER, ALT-TAB, and ENTER in rapid succession. TILES_2 had about a .5 second head-start on TILES_1. I noticed a divergence within the first minute or so, as both became in sync with each other. Just allowing the program to run the attract mode for several minutes, TILES_2 began lagging behind TILES_1, roughly a 13 second lag developed after running for about five minutes. Remember, TILES_2 was re-made with subroutines at the end of the program. I will try this again later with better timing, perhaps using a keyboard macro to start both almost simultaneously. Interesting results so far. Quote Link to comment Share on other sites More sharing options...
RXB Posted August 1, 2020 Share Posted August 1, 2020 BASIC (Beginners' All-purpose Symbolic Instruction Code) The entire point of Basic and XB was to make it easy to use and debug and fix. Line Numbers are easy to deal with and debug, also they give you reference to simple structures. Microsoft and some others created Quick Basic with no line numbers, and really what was the point as it was just a dumbed down version of C after all. Be honest Quick Basic was a flash in pan for most to move to C and abandon Basic entirely. Why waste the time on Quick Basic just jump to easy C or Small C or Assembly and get it over with. (Or Forth!) 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 1, 2020 Author Share Posted August 1, 2020 Not an answer to my question. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted August 1, 2020 Share Posted August 1, 2020 44 minutes ago, OLD CS1 said: I will try this again later with better timing, perhaps using a keyboard macro to start both almost simultaneously. Interesting results so far. If you shared your files, I could also do a test run on MAME for comparison. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 1, 2020 Share Posted August 1, 2020 A simple enough program to test how much difference there is might be: 10 FOR I=1 TO 10000 20 GOSUB 101 ! then try GOSUB 1100 30 NEXT I 40 PRINT I::END 101 RETURN 102 RETURN 103 RETURN ***PUT IN 1000 RETURNS UP TO 1100 RETURN Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 49 minutes ago, mizapf said: If you shared your files, I could also do a test run on MAME for comparison. Here ya go. DSK0.zip Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 23 minutes ago, senior_falcon said: A simple enough program to test how much difference there is might be: I had considered something similar, but I figured a real-world example might be more illuminating. I also looked at some of the routines calling other routines and thought perhaps I might optimize for the higher subroutine placement using the same approach for subs-calling-subs (all called routines to live higher than their callers.) That might be more work, though Quote Link to comment Share on other sites More sharing options...
+mizapf Posted August 2, 2020 Share Posted August 2, 2020 (edited) I'm getting a BAD VALUE for both TILES programs in the line CALL CHAR(I+J,M$) line 121 in TILES_1 and line 250 in TILES_2; in both cases, M$=" " (one space). Maybe something went wrong with the TIFILES import and the DATA lines; do you have a DSK image or a TXT listing? For now I replaced the lines by PRINT I;J;M$. The goal is to find out about speed differences, not to play the game. But I could have an unnoticed bug in TIImageTool in the TIFILES importer. Edit: My result on MAME: TILES_1: 4 min 33 secs TILES_2: 4 min 40 secs I waited until the bottom lines changed 6 times (i.e. until I saw "BY ALAN W RATELIFF II" for the sixth time). Time stopped by hand, started when the screen turned green. Edited August 2, 2020 by mizapf Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 2 hours ago, mizapf said: I'm getting a BAD VALUE for both TILES programs in the line CALL CHAR(I+J,M$) line 121 in TILES_1 and line 250 in TILES_2; in both cases, M$=" " (one space). Maybe something went wrong with the TIFILES import and the DATA lines; do you have a DSK image or a TXT listing? The bad values are a problem I forgot about. Lines 140-145 are CHAR definition DATA statements used by that line, and there are three which begin with a comma but the TIFILES compiler inserts a space in front of those. But, yes, you are correct, we are not playing the game. Thank you. Your results are in line with what I observed. Moving the subroutines to the end of the program did NOT improve execution speed, but rather had a detrimental effect. 3 Quote Link to comment Share on other sites More sharing options...
dgrissom Posted August 2, 2020 Share Posted August 2, 2020 2 hours ago, OLD CS1 said: The bad values are a problem I forgot about. Lines 140-145 are CHAR definition DATA statements used by that line, and there are three which begin with a comma but the TIFILES compiler inserts a space in front of those. But, yes, you are correct, we are not playing the game. Thank you. Your results are in line with what I observed. Moving the subroutines to the end of the program did NOT improve execution speed, but rather had a detrimental effect. I like this topic. Years ago, members of our user's group explored a number of similar themed BASIC/XBASIC topics. I don't remember the results of most of those explorations. I remember some of the tests were to review RAM usage as well as speed. I guess BASIC on the TI is slow or slightly slower ? I've always wanted code to be readable and been a proponent of the "SUB" command. The best I can remember is that it slows the execution speed? However, I am not certain of this due to over 30 years passage. Again, this is a very interesting topic! Thanks.. 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 2, 2020 Share Posted August 2, 2020 30 minutes ago, dgrissom said: I've always wanted code to be readable and been a proponent of the "SUB" command. The best I can remember is that it slows the execution speed? However, I am not certain of this due to over 30 years passage. One thing is clear, you cannot compare SUBs at the end of a program vs at the beginning because it is an XB requirement that they follow the main program. I suppose you could create a long list of SUBs with the same function and check whether the last one takes more/less time to find than the first. ...lee 1 Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 8 minutes ago, Lee Stewart said: One thing is clear, you cannot compare SUBs at the end of a program vs at the beginning because it is an XB requirement that they follow the main program. I suppose you could create a long list of SUBs with the same function and check whether the last one takes more/less time to find than the first. ...lee Knowing now how this works in TI BASIC with the program in VDP RAM, I do plan to do some experiments with XB using my same game. I will run one test like this with just subroutines, and I will take some time to convert subroutines and GOSUBs to subprograms and CALLs. (Although, a couple of subroutines may be difficult as they have multiple entry points. I suppose I could deal with that by using a flag value in the CALL.) I have never worked with subprograms... variables are local in scope, correct? Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 2, 2020 Share Posted August 2, 2020 11 minutes ago, OLD CS1 said: I have never worked with subprograms... variables are local in scope, correct? Yes, that is correct. I think you will find there is a big speed penalty when using subprograms. 1 Quote Link to comment Share on other sites More sharing options...
dgrissom Posted August 2, 2020 Share Posted August 2, 2020 22 minutes ago, senior_falcon said: Yes, that is correct. I think you will find there is a big speed penalty when using subprograms. Glad my memory is not completely gone. ? However, I believe that SUB's are one of the elements that made TI's Extended BASIC better than most of it competitors at that time. Procedures could be developed and tested and easily reused in other projects. (Similar to more advanced programming languages.) TIDBIT allows many of those structures during software development without most of the penalties of the SUB and end of listing subroutines. ... And, at the end of the day, it generates beautiful "spaghetti code". Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted August 2, 2020 Share Posted August 2, 2020 1 hour ago, OLD CS1 said: I have never worked with subprograms... variables are local in scope, correct? Not always; if you are using parameters, the variables in both the subprogram and calling program (which could be another sub) are not 'local' as the sub will pass the values back to the caller if you change the sub variables. You can inhibit this behavior using parenthesis around the variable, e.g., CALL MYSUB((A),B), so that any changes to the parameter in the sub are NOT passed back to the caller. There are some other subtleties and I believe they are fairly well documented in the XB manual. Edit: attempted to add further clarity. Found XB manual online and copied below snip: Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 6 minutes ago, InsaneMultitasker said: Not always; if you are using parameters, the variables in both the subprogram and calling program (which could be another sub) are not 'local' as the sub will pass the values back to the caller if you change the sub variables. Understood, like passing parameters in other language. I just meant that there are no global variables, and the variable "A" in the SUB is wholly separate from the variable "A" in the main program. I have read about SUBs, just never used them. 17 minutes ago, dgrissom said: I believe that SUB's are one of the elements that made TI's Extended BASIC better than most of it competitors at that time. Procedures could be developed and tested and easily reused in other projects. Not certain where I read this, might have been in the XB manual, but I remember reading about making SUBs in stand-alone programs and saving them in MERGE format for import into other programs. I suppose, however, you could do the same thing with subroutines and standardized line numbering, but I am not sure you can MERGE line numbers below ones which already exist. I actually wrote a utility on the Commodore 64 many years ago to do that for my BBS program: I wrote most of it in parts, then merged the parts together with a kind-of BASIC Makefile. 59 minutes ago, senior_falcon said: I think you will find there is a big speed penalty when using subprograms. This is what I recall from previous discussions on the matter. I am not convinced the effort to convert the subroutines into subprograms will be a worthwhile practical investment, but curiosity makes its demands. Quote Link to comment Share on other sites More sharing options...
RXB Posted August 2, 2020 Share Posted August 2, 2020 1 hour ago, senior_falcon said: Yes, that is correct. I think you will find there is a big speed penalty when using subprograms. The speed penalty of using SUB programs is that it creates a list of new Variables that are quite temporary only existing each time the SUB program is used. These temporary variables can persist and not be deleted but when VDP runs low can trigger a recovery routine to delete all temporary variables forcing them to be recreated again later. This is why small programs that do not use very many variables or SUB program variables is slightly faster then large programs with little VDP memory left over forces recovery of VDP space. We have all seen this pause in TI Basic and XB do this at times seemingly at random. At least in XB it is done in Assembly XB ROMS but in TI Basic it is done with less efficiency. If you are going to use SUB programs always make sure you use as few variable names as possible and leave a much VDP available as possible. 3 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted August 2, 2020 Share Posted August 2, 2020 3 hours ago, OLD CS1 said: Knowing now how this works in TI BASIC with the program in VDP RAM, I do plan to do some experiments with XB using my same game. I will run one test like this with just subroutines, and I will take some time to convert subroutines and GOSUBs to subprograms and CALLs. (Although, a couple of subroutines may be difficult as they have multiple entry points. I suppose I could deal with that by using a flag value in the CALL.) I have never worked with subprograms... variables are local in scope, correct? @Willsy wrote a Sprite Designer in XB about 14 years ago that makes pretty heavy use of subprograms. It might be instructive. He later converted it to ALC (see the pinned Developmenmt Thread). ...lee Quote Link to comment Share on other sites More sharing options...
+OLD CS1 Posted August 2, 2020 Author Share Posted August 2, 2020 I just tried this in Extended BASIC on Classic99 using the same timing protocol as what @mizapf used, with the exception of starting the timer at pressing enter on RUN. I came up with 2:59 for low-numbered subroutines, 3:05 for high-numbered subroutines. Another interesting result. Quote Link to comment Share on other sites More sharing options...
Badaboom Posted August 3, 2020 Share Posted August 3, 2020 To code well in basic is to master zen. It isn't the time that matters but the journey. ? 1 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.