LB Booster
General >> General Board >> 4500 lines of JustBASIC code, only 2 errors
http://lbb.conforums.com/index.cgi?board=general&action=display&num=1333350284

4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 2nd, 2012, 07:04am

This program is fantastic!

I've been programming in JustBASIC for the past couple of years and just completed the newest version of a game utility containing ~4500 lines of code. It was the 1st thing I tried to convert with LB Booster and I only received two easy-to-correct errors.

Error#1 - "Missing ( in TAB"
I use the GLOBAL variable Tab$ = CHR$(9) throughout my program and it obviously clashes with the TAB() function, so I changed all references to aTab$ and received no further complaints.

Error#2 - "Duplicate Label"
I used the same [BranchLabelName] inside a couple of subroutines and in the Root Sub. It doesn't complain if the labels inside the subroutines match, but it does if any of them match a label in the Root Sub. I changed the name of the label in the Root Sub and again, all is well.

After that it converted and ran just fine. Nearly all aspects of the program execute 2-3 times faster, except for the main "Rebuild PlayDecks" routine which executes 2-3 times slower. Is this unusual? I was hoping you might take a look at it and see if you can identify which aspect is slowing it down so I can try to re-write it. It does a lot of string manipulation and writing to a LogFile, if either of those might be the culprit. Please check it out at any of the following links, it'll conveniently tell you how long each operation takes after said operation is completed.

JustBASIC Forums Post
JustBASIC Files Archive Post
Manalink 3.0 Forum Post

I'll run my app thought it's paces and do a check of the converted files to make sure all output files are identical to the output of the non-converted original and let you know what I find.

Again, LibertyBASIC Booster is an absolutely dynamite app that I'll use time and time again, and it's sure to be a favorite among the LB and JB community. I'd like both you and Carl Gundel to know that the existence of this app was the tipping point that has made me decide to upgrade from JustBASIC to LibertyBASIC (that and Carl's promise to provide a free upgrade to LB5 when it's released). LB Booster may run the code, but I want LibertyBASIC for the IDE, Debugger, etc. I'd have made this leap sooner, but as a JB programmer I don't visit LB websites and only recently found LB Booster via the Wikipedia article. Perhaps there's some way to make JustBASIC users more aware of it's existence, as it greatly boosts the usablilty of an already highly-usable and free programming language.


Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on Apr 2nd, 2012, 1:23pm

on Apr 2nd, 2012, 07:04am, CirothUngol wrote:
Nearly all aspects of the program execute 2-3 times faster, except for the main "Rebuild PlayDecks" routine which executes 2-3 times slower. Is this unusual? I was hoping you might take a look at it and see if you can identify which aspect is slowing it down so I can try to re-write it.

One thing that might be worth investigating is the use of the WORD$() function. In LBB the version with only two parameters is likely to run considerably more slowly than the version with three parameters (i.e. with an explicit delimiter character). If you know that the delimiter is always a space character, and that there's only ever one space separating the 'words', then you may well find there is a speed improvement by for example replacing:

Code:
WORD$(BreakPD$(Z), 3) 

with

Code:
WORD$(BreakPD$(Z), 3, " ") 

You use WORD$() frequently in the code which is running more slowly than expected, so if possible try adding the third parameter to every one.

Richard.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 3rd, 2012, 05:20am

Yea, I thought WORD$() would've been the culprit. I've used several BASICs (starting on AtariBASIC in the early '80s) and it's always been a slow function. I usually try to avoid it for that reason (using INSTR() & MID$() instead), but in this case it's practically necessary. If you will allow me a bit of explanation:

The "Official" format for the content of these PlayDeck.dck files uses Tabs (ie CHR$(9)) like this: ".ID#<TAB>Qty<TAB>CardName". However, many of the files that are imported were either made by other applications, saved in a text editor that doesn't support Tabs, or even typed by hand. So the delimeter will either be a Tab or 1-4 Spaces.
WORD$()'s ability to delimit by "WhiteSpace" in this way seems rather indispensable. Not that you'd care to turn this into a coding discussion, but if you can think of a non-messy way to seperate the words given those parameters I'm quite open to suggestions.

I noticed that you'd added an Escape Character (!) for using actual BBC BASIC code so I thought to look for WORD$() in the documentation, but BBC doesn't seem to have it (is this correct?). I believe that'd be a first with the 5-6 BASICs I've used.

Thanx for the reply, it's most appreciated.

Edit-
Oh yea, I forgot to mention that I found no issues with the output files from my app. The only differences were in the sort-order of the text files (which you've mentioned) and LBB's ability to properly handle TABs when writing to\reading from a TextWindow\TextEditor (mentioned here). Identical output... sweet.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on Apr 3rd, 2012, 2:05pm

on Apr 3rd, 2012, 05:20am, CirothUngol wrote:
if you can think of a non-messy way to seperate the words given those parameters I'm quite open to suggestions.

If you can be confident that a file will be either entirely TAB-delimited or entirely space-delimited you could test it initially to see which kind it is. Then at least you could use the faster version of WORD$ - with the third parameter set to CHR$(9) - when you know it's the TAB-delimited variety.

Another suggestion would be to pre-process the files (maybe using a separate program) so that they all consistently use TAB delimiters. That way the conversion of white-space to TABs would be a once-off operation for each file and, once done, you can thereafter use the fast version of WORD$.

Richard.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 5th, 2012, 04:31am

Thanx for the ideas. I already pre-process the files when importing them (to check for validity, format, etc.), so I'll just format them with TABs while doing that.

I added delimeters to the WORD$()s and used TAB formatted files, but the speed increase was only a few percent. I started testing single functions inside a FOR I = 0 TO 1000000...NEXT loop to see if I could find what was dragging it down.

The blank loop was 20-25 times faster in LBB than JB. Assigning a variable was 10-15 times faster. String ops (LEFT$(), RIGHT$(), MID$(), etc.) were 5-8 times faster, as was WORD$() with a delimeter. Even without the delimeter, WORD$() was still about 25% faster in LBB than JB. Although it seems that PRINTing to a STATICTEXT widget is about 10-20% faster in JB than LBB, my app doesn't do that much displaying.

I finally discovered the culprit... it's the SCAN statement. Try this in both JB and LBB Code:
StartTime = TIME$("ms")
FOR I = 0 TO 1000000
NEXT I
PRINT "Blank Loop: "; JBtimeSince$(StartTime)
PRINT ""

StartTime = TIME$("ms")
FOR I = 0 TO 1000000
    SCAN
NEXT I
PRINT "SCAN Loop: "; JBtimeSince$(StartTime)

END

' FUNCTION '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Returns a string$ detailing how much time has expired since StartTime
' (e.g. 2 hrs, 14 min, 36.748 sec). If a time is zero it won't be included,
' except for 0 min, when hours are also present. Just set StartTime = TIME$("ms")
' at the beginning of a process and then call JBtimeSince$(StartTime) at the end.
' by CirothUngol
 FUNCTION JBtimeSince$(StartTime)
    LET EndTime = TIME$("ms")
    LET Hours$ = " hrs, "
    LET Minutes$ = " min, "
    LET Seconds$ = " sec"
    IF EndTime >= StartTime THEN
        EndTime = EndTime - StartTime
    ELSE
        EndTime = EndTime + (86400000 - StartTime)
    END IF
    IF EndTime > 3600000 THEN
        JBtimeSince$ = STR$(INT(EndTime / 3600000)) + Hours$
        EndTime = EndTime MOD 3600000
    END IF
    IF (EndTime > 60000) OR (JBtimeSince$ <> "") THEN
        JBtimeSince$ = JBtimeSince$ + STR$(INT(EndTime / 60000)) + Minutes$
        EndTime = EndTime MOD 60000
    END IF
    JBtimeSince$ = JBtimeSince$ + STR$(INT(EndTime / 1000)) + "."
    EndTime = EndTime MOD 1000
    IF EndTime < 100 THEN JBtimeSince$ = JBtimeSince$ + "0"
    IF EndTime < 10 THEN JBtimeSince$ = JBtimeSince$ + "0"
    JBtimeSince$ = JBtimeSince$ + STR$(EndTime) + Seconds$

 END FUNCTION 
It's about 20 times faster in JB than LBB, and all of the hyper-repetitious loops in my program have one in there (for use with the "Abort" button). I did a global replace to comment them out and voilą, the LBB conversion runs at least 4-5 times faster than it's JB counterpart.

Thanx again for the help, and for making this fantastic, easy-to-use converter... and for giving it away absolutely free!
Together JB and LBB are an awesome toolchest.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on Apr 5th, 2012, 08:30am

on Apr 5th, 2012, 04:31am, CirothUngol wrote:
I finally discovered the culprit... it's the SCAN statement.

That's interesting. If there are no events to process SCAN does very little in LBB, but inevitably there is the overhead of calling a BBC BASIC function.

If the reason for using SCAN in your program is to test for a user abort, I would not expect it to matter if there is a slight delay before the abort is acknowledged. Therefore perhaps there are some places where the SCAN can be safely omitted.

Richard.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 5th, 2012, 1:14pm

Quote:
perhaps there are some places where the SCAN can be safely omitted.

Yup! I originally placed many SCAN statements inside the deepest nested loops so that the user would see an immediate response to the "Abort" button (JB is kinda slow). By moving the SCANs to higher loops it gets called far fewer times and LBB is fast enough that the user still sees a very immediate response... it's the best of both worlds.

My next release of the PlayDeck Analyser will be 20 times smaller and 5 times faster thanx to LBB. In fact, I'm working on a stripped-down command-line version (no GUI, Bells or Whistles) for inclusion with the next Manalink update... one usually has to be a C programmer to get to do that.

This app truly rocks.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on Apr 5th, 2012, 9:46pm

on Apr 5th, 2012, 1:14pm, CirothUngol wrote:
This app truly rocks.

I'm pleased you like it. Now we just have to persuade the JB/LB folk that LBB isn't a threat to Carl's livelihood, but can actually encourage people to buy LB. I've always said that might be the case, but you've confirmed it.

At present any mention of LBB is banned in the JB and LB support groups, so most people never get to find out about it.

Richard.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 6th, 2012, 03:34am

Oh... I never really thought about it, but I suppose I could see that. Although I imagine that most of the attitude would come from Mr. Gundel's supporters as opposed to the man himself. Surely he would realize that in order for someone to effectivly use LBB, they either need LB for the IDE and related utilities\support, or they are already an experienced LibertyBASIC programmer... meaning they already own LB. This app was definitely the proverbial "kick-in-the-pants" that made me buy LB; and coupled with JB it's a simple, easy, accessible and free alternative for people who have no disposable income (like me, but I'm getting LB as a birthday gift. Huzzah!).

I could especially see LBB boosting JB's popularity as well as its sleekness and speed. See, JB is easy... Really easy. No, easier than that. It's the easiest. I spent a couple of weeks about 2-3 years ago looking at programming-languages when I decided to start programming again after a 20-year lapse. VB, LOGO, Lua, Perl, KDP, C#... I inspected a slew of "easy" languages, looked at their syntax and spent time on tutorials (if available). In the end, it came down to JustBASIC or Euphoria. I'm sure as the writer of a computer language you may be familiar with the latter of the two, but just in case you aren't please check it out. It has an amazingly free and dynamic variable structure, highly simplistic syntax, and an uber-fast interpreter (one of the fastest, I think). Unlike many languages that claim to be simple, easy, versatile and powerful, those two actually are... and I chose JB because of the great IDE\Debugger, extensive tutorials\documentation\community support, and highly-familiar BASIC syntax\procedural-style programming. Knowing that it was possible to "compile" JB to a single, tiny, fast executable would surely bring more interest, and maybe even help legitimize JB as a *gasp* "real programming language".
I see only good coming from this.

There will always be haters, but I for one am truly grateful that such a useful and easy-to-use utility as LibertyBASIC Booster is now permanently in my toolbox, along with JustBASIC, absolutely free!

Quote:
chau·vin·ism [shoh-vuh-niz-uhm] -n
excessive, unreasonable, zealous, aggressive or blind enthusiasm for or biased devotion to any group, attitude, person, or cause.
As a long-time and occasional member of the Anime, Comic and Magic: The Gathering communities, I am no stranger to this concept.
No matter who, what or where you are... never be this guy. ^_^
Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on Apr 6th, 2012, 09:26am

on Apr 6th, 2012, 03:34am, CirothUngol wrote:
In the end, it came down to JustBASIC or Euphoria....Unlike many languages that claim to be simple, easy, versatile and powerful, those two actually are

I would say that BBC BASIC (which presumably you ruled out because it isn't free) is better than either, but then I'm thoroughly biassed! Personally I don't consider either Liberty BASIC or Just BASIC to be serious contenders, because they are far too limited: there are so many things that it's either impossible to do or can only be done using a helper DLL (and that's not an option in JB).

Admittedly there are some things that are considerably easier to do in LB/JB than in BBC BASIC, and that's something that has been exercising my attention of late, but personally I'd rather use a language which is more powerful even if it's slightly more difficult.

You might find it interesting to read my blog post from a few years ago comparing Liberty BASIC with BBC BASIC:

http://bbcbasic.blogspot.co.uk/2008/11/theres-little-doubt-that-main.html

Richard.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 6th, 2012, 1:10pm

Quote:
...(which presumably you ruled out because it isn't free)...
You got it. I forgot to mention that being free of charge was a prerequisite for any language I was going to use, because I'm not a programmer and I'm on a super-tight budget.
I'm sure that BBC BASIC is wonderfully powerful and versatile, but in exchange it also must be more complex. In general, I'm looking to manipulate simple data files, nothing very difficult. Now that I've become accustomed to the JB\LB style, I'd prefer to stick with it.

I used to program in a great 6502 compiler language named Action! on the Atari800XL. It was easy and super-fast... but never became very popular. To this day I still don't understand why. There's no accounting for taste. ^_^
Re: 4500 lines of JustBASIC code, only 2 errors
Post by CirothUngol on Apr 10th, 2012, 2:42pm

Hiya!
I've just hit a snag while adding some code to my program. It runs fine in JustBASIC but won't run under LBB. Before I try to isolate an example and post some code to illustrate, what is "Internal error 20"? LBB hits this error and then unceremoniously exits.

Is there a maximum size limit of the code to convert (mine is over 4500 lines)?
Is there a maximum distance between a function and the code that calls it (4096 lines, perhaps)?

Edit1 -
I think I've narrowed it down to a new function I wrote using BYREF... again, I'll see if I can isolate it and post some sample code.

Edit2 -
I was unable to replicate the error in a small amount of code, but it definately has something to do with the BYREF in the Function. It only errors when called from a specific Subroutine, but works just fine when called from everywhere else (Subroutines and Root). LBB will also compile and run if I remove the BYREF from the Function.

I've circumvented the issue by writing the Function into the calling Subroutine as a GoSub. If you're interested in seeing the offending code, I could zip it up and post it somewhere.

Thanks for any help, and for the Killer App.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by tsh73 on May 2nd, 2012, 06:06am

Richard said:
Quote:
Personally I don't consider either Liberty BASIC or Just BASIC to be serious contenders, because they are far too limited: there are so many things that it's either impossible to do or can only be done using a helper DLL (and that's not an option in JB).

Well, there is such thing as "good enough". That's why I routinely use JB, even having bought LB.
Re: 4500 lines of JustBASIC code, only 2 errors
Post by Richard Russell on May 2nd, 2012, 08:13am

on Apr 10th, 2012, 2:42pm, CirothUngol wrote:
what is "Internal error 20"?

'Internal error 20' is "Number too big", i.e. a value won't fit in a 32-bit integer. I would certainly be interested in seeing the code which causes it.

Richard.