• Please review our updated Terms and Rules here

Transparent Mode

carlsson said:
In the case of Z88, I think the answer is BBC Basic, which is known to be really quick and elegant on both 6502 and Z80 implementations. There is a Sinclair Spectrum implementation of BBC Basic too, I think, but I don't know if it is freely distributable and how common it is.
Yeah, I thought that might be the case, too. The Sinclair & Amstrad (CP/M) versions of BBC are available at the link I posted above, as well as a plain-vanilla CP/M version.
I can try the prime numbers on some computers/emulators when I get home. The most interesting part with the Kilobaud benchmarks is to see how time differs between each benchmark, and which factors slow down more than others. In almost all cases except Sinclair Basic, using numeric constants is slower than using variables.

That makes sense, since a variable has to be re-calculated each time it is used, but a constant is always "known" to the program. (I wonder if numeric variables take longer than strings, since string variables only have to be stored and read when needed?)

--T
 
Terry Yager said:
carlsson said:
In almost all cases except Sinclair Basic, using numeric constants is slower than using variables.
That makes sense, since a variable has to be re-calculated each time it is used, but a constant is always "known" to the program. (I wonder if numeric variables take longer than strings, since string variables only have to be stored and read when needed?)
Err? I can't speak for all Basic interpretations, but in Commodore Basic, which is a Microsoft derivate:
  • a decimal (A) or integer (A%) variable allocates 7 bytes of space and appears to be evaluated in the internal format when it is allocated
  • a string (A$) variable allocates 7 bytes of space, but points into the program itself
  • whenever a string is changed or concatenated, it is "evaluated" into a local copy and grows in size (see below)
  • a numeric constant doesn't allocate space anywhere and thus has to be evaluated everytime it appears
  • an array up to 10 elements is automatically dimensioned when one element is accessed if the array isn't already dimensioned
  • manually dimensioning smaller arrays will save space
  • an array of integer variables (9 bytes + 2 per element) takes less space than an array of decimal variables (12 bytes + 5 per element)
This line will thus only take 7 bytes after running:
10 A$="A VERY LONG STRING INDEED"

while adding this line, the program instead will take 52 bytes extra:
15 A$=A$+" BUT NOT THE LONGEST POSSIBLE"

By the way, your prime number program calculating primes between 29000 and 32767 took 7 minutes and 38 seconds to execute on the VIC-20 (using the VICE emulator in warp mode). I made the following significant changes to the listing:

30 P%=32767/100 : REM P% will hold the integer value
60 TI$="000000" : REM resetting the timer
90 IF INT(I/J)*J=I THEN 140 : REM instead of I MOD J = 0

Taking away the output just reduced the execution speed by six seconds.
 
Using decimal variable P instead of P% unexpectadly increased execution time by one second (7m33s), which probably is an error in measurement.

As FOR J% is not allowed, I tried to unroll the loops into IF statements: 13m13s (integer) or 12m31s (decimal) variables, which also could be realized by my previously posted benchmarks.
 
carlsson said:
Err? I can't speak for all Basic interpretations, but in Commodore Basic, which is a Microsoft derivate:
  • a decimal (A) or integer (A%) variable allocates 7 bytes of space and appears to be evaluated in the internal format when it is allocated

  • Of course a variable must be evaluated when it is first defined, but does this mean that it is not evaluated again unless it has been changed, or is it re-evaluated every time it is encountered (to determine if it has changed)?
    [*] a string (A$) variable allocates 7 bytes of space, but points into the program itself
    Is this because the string is stored within the program itself, and therefore does not need to allocate any extra (external) storage space elsewhere in memory? If this is the case, what is the purpose of BASIC reserving some space (at the top of RAM usually) for string storage, or doesn't Commodore BASIC reserve any string space?
    [*] whenever a string is changed or concatenated, it is "evaluated" into a local copy and grows in size (see below)
    Right (I think)... The string only needs to be re-evaluated if it has been changed. (Like the numeric variable above?)
    [*] a numeric constant doesn't allocate space anywhere and thus has to be evaluated everytime it appears
    The constant does not need to be stored because it is always known to the program, since it never changes, so why does it need to be evaluated whenever it is encountered?
    [*] an array up to 10 elements is automatically dimensioned when one element is accessed if the array isn't already dimensioned
    ...?
    [*] manually dimensioning smaller arrays will save space
    ...??
    [*] an array of integer variables (9 bytes + 2 per element) takes less space than an array of decimal variables (12 bytes + 5 per element)
...???
Don't mind me, I've never understood arrays. (I'm (obviously?) not a programmer, and although assembly language makes some kinda sense to me (dealing with the hardware at it's own level), I've never been able to grok BASIC at all
This line will thus only take 7 bytes after running:
10 A$="A VERY LONG STRING INDEED"

while adding this line, the program instead will take 52 bytes extra:
15 A$=A$+" BUT NOT THE LONGEST POSSIBLE"

Why is this? How is it that the second half of the string adds so many bytes of storage?
By the way, your prime number program calculating primes between 29000 and 32767 took 7 minutes and 38 seconds to execute on the VIC-20 (using the VICE emulator in warp mode). I made the following significant changes to the listing:
It isn't my program (I wish)...it's a PD thing I copied from a (e-)book.
30 P%=32767/100 : REM P% will hold the integer value
60 TI$="000000" : REM resetting the timer
90 IF INT(I/J)*J=I THEN 140 : REM instead of I MOD J = 0
I'll try changing those values and run the benchmark again to see how much difference it makes.
Taking away the output just reduced the execution speed by six seconds.
But you're using a CRT, right? That wouldn't take as much of a hit as a (notoriously s-l-o-w) LCD display, would it?

--T
 
Terry Yager said:
Of course a variable must be evaluated when it is first defined, but does this mean that it is not evaluated again unless it has been changed, or is it re-evaluated every time it is encountered (to determine if it has changed)?
Yes, AFAIK, once evaluated it is stored in internal MFLPT (floating-point) form. If changed, it is of course re-evaluated.
  • [*] a string (A$) variable allocates 7 bytes of space, but points into the program itself
    Is this because the string is stored within the program itself, and therefore does not need to allocate any extra (external) storage space elsewhere in memory? If this is the case, what is the purpose of BASIC reserving some space (at the top of RAM usually) for string storage, or doesn't Commodore BASIC reserve any string space?
    It reserves space, but as long as the string is identical to the listed one, there is no need to copy the value into work memory. As I wrote, when the string is changed, it is first copied and will thus take more memory.
    The constant does not need to be stored because it is always known to the program, since it never changes, so why does it need to be evaluated whenever it is encountered?
    Because it is stored like text "12632", not a hexadecimal or MFLPT value. The interpreter only tokenizes keywords when the program is inputted, not evaluating constants. Other dialects may do both.
    [*] an array up to 10 elements is automatically dimensioned when one element is accessed if the array isn't already dimensioned
    [*] manually dimensioning smaller arrays will save space
    [*] an array of integer variables (9 bytes + 2 per element) takes less space than an array of decimal variables (12 bytes + 5 per element)
    ...?
    ...??
    ...???
I just wanted to give an answer why integer variables exist, as they are more limited and slower (stored in integer rather than MFLPT format, so it has to be converted everytime it is used) than decimal variables.

This line will thus only take 7 bytes after running:
10 A$="A VERY LONG STRING INDEED"

while adding this line, the program instead will take 52 bytes extra:
15 A$=A$+" BUT NOT THE LONGEST POSSIBLE"

Why is this? How is it that the second half of the string adds so many bytes of storage?
Because in the first case, a string variable is set up but pointing to the string inside the program. In the second case, the variable is modified and thus its value has to be copied and modified in workspace. :)

Taking away the output just reduced the execution speed by six seconds.
But you're using a CRT, right? That wouldn't take as much of a hit as a (notoriously s-l-o-w) LCD display, would it?
Right. I think it depends on how the PRINT and screen output is performed. On a Spectrum, Amstrad or all the other systems which seem to plot the text on a high resolution screen, I'm afraid it could make quite a lot of difference despite running on a CRT, but a character-based display where the video chip only has to fetch 8x8 pixels of character data from ROM, it may not make much of a difference. We'll wait for CP/M User to try the prime numbers with and without display.
 
"carlsson" wrote:

> Right. I think it depends on how the PRINT
> and screen output is performed. On a
> Spectrum, Amstrad or all the other systems
> which seem to plot the text on a high
> resolution screen, I'm afraid it could make
> quite a lot of difference despite running on
> a CRT, but a character-based display where
> the video chip only has to fetch 8x8 pixels
> of character data from ROM, it may not
> make much of a difference. We'll wait for
> CP/M User to try the prime numbers with
> and without display.

Oh we're onto Prime Number programs in
this thread now! ;-)

I had to do some modifications with your little
program so it worked on my Amstrad.

Here they are:

30 P = 32767/100
No such thing called DIV in Locomotive BASIC

60 A = time/300

Not sure about this one. Time/300 is the value
used to determine what 1 sec is. A needed to
be a value & not some string or character
variable.

150 B = time/300

The same as 60.

160 & 170 Changed String variables to Integer
variables (I hope! :)

Now the times I had:

3 min 55 secs with display & 3 min 41 secs
without display. Doesn't make any real
difference, but then if I'm doing something
wrong with the time statement, then it should
take less time.

So unless you've just called time$ as another
string, then maybe that's the problem & I
should call it something else (like T$ for
example). Time is actually a function on my
Amstrad! :)

Cheers,
CP/M User.
 
CP/M User said:
Oh we're onto Prime Number programs in this thread now! ;-)
Yep, "transparent" prime numbers if you decide not to print them.

3 min 55 secs with display & 3 min 41 secs without display.
Hmm.. that looks speedy, but maybe the Locomotive Basic is speedy on the Amstrad? You could time it by hand to make sure you were not fooled.
 
"carlsson" wrote:

>> 3 min 55 secs with display & 3 min 41
>> secs without display.

> Hmm.. that looks speedy, but maybe the
> Locomotive Basic is speedy on the
> Amstrad? You could time it by hand to
> make sure you were not fooled.

I used a stop watch for this & so there's
no way that would be incorrect, unless
I've misinterpreted this program for
Locomotive BASIC. The Amstrad runs
at 4Mhz (about the same as a Spectrum),
but it's BASIC seems more advanced. I
know it's quicker than Turbo Pascal in
some regards, so it's not bad! :) If
anything my timing might be a couple of
seconds out, meaning it could be 3
minutes & 51 seconds.

Cheers,
CP/M User.
 
Back
Top