• C64 BASIC - what's faster INT() or %? Plus benefits of DEF FN A()

    From Shaun Bebbington@3:770/3 to All on Mon Apr 16 09:20:04 2018
    There seems to be two ways to do integers on the C64 (and yes I know floats are
    fastest), I was wondering about these two methods of generating a random positive number between 1 and 64 inclusive:

    10 X=INT(64*RND(0)+1)

    or

    10 X%=64*RND(0)+1

    The latter saves two whole bytes, but is it faster to convert to integer directly with the INT keyword, or is the implicit declaration below faster?

    Second question, let's say you want to generate a random number in multiple places, you could use the above several times in a listing, but one could also define a function as I understand it, like:

    0 DEF FN A(X)=X*RND(0)

    So each time in your listing, you will have,

    10 X%=FN A(39): Y%=FN A(24)
    ...
    100 S%=FN A(10)+1: D%=FN A(10)+1

    etc...

    Other than less typing throughout the program (where you might have lots of repeated random number generation in this example), are there any benefits to using CBM functions? Does it save bytes overall would be perhaps one that I could think of.

    Many thanks,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Whammo@3:770/3 to All on Mon Apr 16 14:08:11 2018
    10 X=INT(64*RND(0)+1)

    Here, X is a defined as a float, so you're using the variable space of a float and explicitly calling the INT function.

    or

    10 X%=64*RND(0)+1

    Here, X% is defined as an integer it uses less space and it only needs to read and write the bytes of an integer.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Whammo@3:770/3 to All on Mon Apr 16 14:20:49 2018
    Other than less typing throughout the program (where you might have lots of
    repeated random number generation in this example), are there any benefits to using CBM functions? Does it save bytes overall would be perhaps one that I could think of.

    Many thanks,

    Shaun.

    Other than that, it's faster to inline code than to define a function.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Shaun Bebbington@3:770/3 to Whammo on Mon Apr 16 14:29:27 2018
    On Monday, 16 April 2018 22:20:51 UTC+1, Whammo wrote:
    Other than less typing throughout the program (where you might have lots of
    repeated random number generation in this example), are there any benefits to using CBM functions? Does it save bytes overall would be perhaps one that I could think of.

    Many thanks,

    Shaun.

    Other than that, it's faster to inline code than to define a function.

    Thanks for the info.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Shaun Bebbington@3:770/3 to All on Tue Apr 17 05:21:09 2018
    For clarification, which is faster?

    10 X=INT(64*RND(0)+1)

    or

    10 X%=64*RND(0)+1

    Thanks,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From frank@3:770/3 to Shaun Bebbington on Tue Apr 17 18:49:52 2018
    Shaun Bebbington <shaun@square-circle.co.uk> wrote:
    For clarification, which is faster?

    10 X=INT(64*RND(0)+1)

    or

    10 X%=64*RND(0)+1


    you can enclose the two statements one at a time inside a 200-300 counts FOR-NEXT cycle and easily verify yourself which is faster.
    Frank

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From John H. Guillory@1:396/60 to Shaun Bebbington on Tue Apr 17 14:46:19 2018
    For clarification, which is faster?
    10 X=INT(64*RND(0)+1)
    or
    10 X%=64*RND(0)+1

    Just guessing, I'd say the second one, or 10 X%=64*RND(0)+1
    because in the first, your converting 64*RNND(0)+1 to an integer, then converting back to a single precision decimal point value.

    --- Mystic BBS v1.12 A38 2018/01/01 (Windows/32)
    * Origin: KF5QEO's Shack (1:396/60)
  • From Shaun Bebbington@3:770/3 to All on Wed Apr 18 06:38:34 2018
    Thanks for the hints all. I'll do some bench mark testing or whatever :-)

    Regards,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Janne Johansson@2:221/6 to Shaun Bebbington on Wed Apr 18 18:35:50 2018
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of repetitions is too hard to figure it out, then the answer isn't really important.

    ---
    * Origin: nntp://news.fidonet.fi - Lake Ylo - Finland (2:221/6)
  • From Shaun Bebbington@3:770/3 to Janne Johansson on Wed Apr 18 10:37:18 2018
    On Wednesday, 18 April 2018 16:41:28 UTC+1, Janne Johansson wrote:
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of repetitions is too hard to figure it out, then the answer isn't really important.

    Hey! Good hint.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Janne Johansson@2:221/6 to Shaun Bebbington on Thu Apr 19 10:08:48 2018
    On 2018-04-18 09:37, Shaun Bebbington : Janne Johansson wrote:
    On Wednesday, 18 April 2018 16:41:28 UTC+1, Janne Johansson  wrote:
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or
    whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of
    repetitions is too hard to figure it out, then the answer isn't really
    important.

    Hey! Good hint.

    I noticed (after sending of course) that it may have been perceivable as
    a harsh statement, hinting at lazyness or something, I meant more along
    the lines of "if you try 100 loops and can't make out the difference,
    then try 1000 loops then try 10k loops and so on, the difference might
    be so small that its not worth coding your BASIC programs with %
    sprinkled here and there for optimization reasons, but just go for
    normal ordinary readability and simplicity since performance is then
    bound by something else like algorithmic complexity and not the one-time conversions from ints to floats and back".

    If you really need a basic program to run faster, there are a lot of
    compilers that pre-calculate and pre-parse and then make some kind of
    machine language equivalent program out of it which you can run and
    which will be lots faster. If that isn't fast enough still, code
    important parts in ASM directly or at least code it up in CC65 using
    C for some middle ground between compiled BASIC and doing it all in
    ASM yourself.

    ---
    * Origin: nntp://news.fidonet.fi - Lake Ylo - Finland (2:221/6)
  • From Shaun Bebbington@3:770/3 to All on Wed Apr 18 23:34:56 2018
    After some experimenting it seems that I've been doing random numbers in CBM BASIC completely wrong all of these years. Worse still, all of the examples in the printed literature at the time had the wrong example as well. I assume this
    is because firstly
    the least efficient way is more human readable, and secondly it would allow the
    range of numbers to exceed a 16-bit signed integer range.

    Here is the fastest way to make peusdo-random numbers happen inside the CBM BASIC interpreter, assuming you want a positive integer of between zero and R:

    X%=RND(.)*R

    So, if you require a number higher than +32767, this is the fastest way:

    X=INT(RND(.)*R)

    The ordering seems to be important for optimisation as well, as R*RND(.) is slower because the interpreter re-orders the calculation on the fly according to its precedence.

    I was never made aware of any of these facts as a child BASIC programmer.

    Regards,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Shaun Bebbington@3:770/3 to Janne Johansson on Thu Apr 19 01:14:37 2018
    On Thursday, 19 April 2018 08:14:28 UTC+1, Janne Johansson wrote:
    On 2018-04-18 09:37, Shaun Bebbington : Janne Johansson wrote:
    On Wednesday, 18 April 2018 16:41:28 UTC+1, Janne Johansson  wrote:
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or
    whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of >> repetitions is too hard to figure it out, then the answer isn't really
    important.

    Hey! Good hint.

    I noticed (after sending of course) that it may have been perceivable as
    a harsh statement, hinting at lazyness or something, I meant more along
    the lines of "if you try 100 loops and can't make out the difference,
    then try 1000 loops then try 10k loops and so on, the difference might
    be so small that its not worth coding your BASIC programs with %
    sprinkled here and there for optimization reasons, but just go for
    normal ordinary readability and simplicity since performance is then
    bound by something else like algorithmic complexity and not the one-time conversions from ints to floats and back".

    If you really need a basic program to run faster, there are a lot of compilers that pre-calculate and pre-parse and then make some kind of
    machine language equivalent program out of it which you can run and
    which will be lots faster. If that isn't fast enough still, code
    important parts in ASM directly or at least code it up in CC65 using
    C for some middle ground between compiled BASIC and doing it all in
    ASM yourself.

    Yes Blitz BASIC seems to do a reasonably good job at this. As for C, well I love C. My thinking is like this: optimize BASIC, then compile. That should get
    the best results.

    Regards,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Holger@3:770/3 to All on Thu Apr 19 13:21:31 2018
    Am 17.04.2018 um 04:46 schrieb John H. Guillory:
    SB> For clarification, which is faster?
    SB> 10 X=INT(64*RND(0)+1)
    SB> or
    SB> 10 X%=64*RND(0)+1

    Just guessing, I'd say the second one, or 10 X%=64*RND(0)+1
    because in the first, your converting 64*RNND(0)+1 to an integer, then converting back to a single precision decimal point value.

    Effectively, calculations always happen in floating point, and INT()
    returns a FP value in the floating point accu. Conversion will take
    place on assignment to the destination variable. The INT() operation is
    similar to the truncation operation to fit the FP accu value into X%.
    In fact, the major difference is that the first line has to copy 5 bytes
    into a variable space and the second will copy 2 bytes.

    There isn't even an advantage in space requirement for the variable;
    both need 7 bytes, i.e. 2 bytes for the name (like A1 or B2% or C3$) and
    5 for the value; an integer variable just wastes 3 bytes for the value.
    It is different for integer vs. float arrays; in this case a % value is
    indeed packed into 2 bytes.

    -hl

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Shaun Bebbington@3:770/3 to Holger on Thu Apr 19 12:53:27 2018
    On Thursday, 19 April 2018 12:21:32 UTC+1, Holger wrote:
    Am 17.04.2018 um 04:46 schrieb John H. Guillory:
    SB> For clarification, which is faster?
    SB> 10 X=INT(64*RND(0)+1)
    SB> or
    SB> 10 X%=64*RND(0)+1

    Just guessing, I'd say the second one, or 10 X%=64*RND(0)+1
    because in the first, your converting 64*RNND(0)+1 to an integer, then converting back to a single precision decimal point value.

    Effectively, calculations always happen in floating point, and INT()
    returns a FP value in the floating point accu. Conversion will take
    place on assignment to the destination variable. The INT() operation is similar to the truncation operation to fit the FP accu value into X%.
    In fact, the major difference is that the first line has to copy 5 bytes
    into a variable space and the second will copy 2 bytes.

    There isn't even an advantage in space requirement for the variable;
    both need 7 bytes, i.e. 2 bytes for the name (like A1 or B2% or C3$) and
    5 for the value; an integer variable just wastes 3 bytes for the value.
    It is different for integer vs. float arrays; in this case a % value is indeed packed into 2 bytes.

    -hl

    Thanks for the information, but using X% still saves two bytes and some processor time if used correctly. I'm looking for optimised BASIC as in speed where possible, rather than technically perfect BASIC which could never be achieved anyway.

    I get enough performance from Blitz to be happy :-)

    Regards,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Herr Doktor@3:770/3 to Janne Johansson on Fri Apr 27 15:57:15 2018
    I've used all the compilers, and prefer Petspeed.

    On Thu, 19 Apr 2018 10:08:48 +1200,
    nospam.Janne.Johansson@f6.n221.z2.binkp.net (Janne Johansson) wrote:

    On 2018-04-18 09:37, Shaun Bebbington : Janne Johansson wrote:
    On Wednesday, 18 April 2018 16:41:28 UTC+1, Janne Johansson  wrote:
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or
    whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of >>> repetitions is too hard to figure it out, then the answer isn't really
    important.

    Hey! Good hint.

    I noticed (after sending of course) that it may have been perceivable as
    a harsh statement, hinting at lazyness or something, I meant more along
    the lines of "if you try 100 loops and can't make out the difference,
    then try 1000 loops then try 10k loops and so on, the difference might
    be so small that its not worth coding your BASIC programs with %
    sprinkled here and there for optimization reasons, but just go for
    normal ordinary readability and simplicity since performance is then
    bound by something else like algorithmic complexity and not the one-time >conversions from ints to floats and back".

    If you really need a basic program to run faster, there are a lot of >compilers that pre-calculate and pre-parse and then make some kind of
    machine language equivalent program out of it which you can run and
    which will be lots faster. If that isn't fast enough still, code
    important parts in ASM directly or at least code it up in CC65 using
    C for some middle ground between compiled BASIC and doing it all in
    ASM yourself.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Herr Doktor@3:770/3 to shaun@square-circle.co.uk on Fri Apr 27 15:55:56 2018
    What is the range of the random number you wish to generate? Have you considered just reading the value of the system timer?

    On Mon, 16 Apr 2018 09:20:04 -0700 (PDT), Shaun Bebbington <shaun@square-circle.co.uk> wrote:

    There seems to be two ways to do integers on the C64 (and yes I know floats are fastest), I was wondering about these two methods of generating a random positive number between 1 and 64 inclusive:

    10 X=INT(64*RND(0)+1)

    or

    10 X%=64*RND(0)+1

    The latter saves two whole bytes, but is it faster to convert to integer directly with the INT keyword, or is the implicit declaration below faster?

    Second question, let's say you want to generate a random number in multiple places, you could use the above several times in a listing, but one could also define a function as I understand it, like:

    0 DEF FN A(X)=X*RND(0)

    So each time in your listing, you will have,

    10 X%=FN A(39): Y%=FN A(24)
    ...
    100 S%=FN A(10)+1: D%=FN A(10)+1

    etc...

    Other than less typing throughout the program (where you might have lots of repeated random number generation in this example), are there any benefits to using CBM functions? Does it save bytes overall would be perhaps one that I could think of.

    Many thanks,

    Shaun.

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Shaun Bebbington@3:770/3 to Herr Doktor on Mon Apr 30 01:36:11 2018
    On Friday, 27 April 2018 20:57:21 UTC+1, Herr Doktor wrote:
    I've used all the compilers, and prefer Petspeed.

    I couldn't get PETSpeed to work - maybe it doesn't like the way that I obfuscate and minimise my symbolic listings or something?

    Regards,

    Shaun

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From Charles Richmond@3:770/3 to Holger on Mon May 7 14:06:45 2018
    On 4/19/2018 6:21 AM, Holger wrote:
    Am 17.04.2018 um 04:46 schrieb John H. Guillory:
      SB> For clarification, which is faster?
      SB> 10 X=INT(64*RND(0)+1)
      SB> or
      SB> 10 X%=64*RND(0)+1

    Just guessing, I'd say the second one, or 10 X%=64*RND(0)+1
    because in the first, your converting 64*RNND(0)+1 to an integer, then
    converting back to a single precision decimal point value.

    Effectively, calculations always happen in floating point, and INT()
    returns a FP value in the floating point accu. Conversion will take
    place on assignment to the destination variable. The INT() operation is similar to the truncation operation to fit the FP accu value into X%.
    In fact, the major difference is that the first line has to copy 5 bytes
    into a variable space and the second will copy 2 bytes.

    There isn't even an advantage in space requirement for the variable;
    both need 7 bytes, i.e. 2 bytes for the name (like A1 or B2% or C3$) and
    5 for the value; an integer variable just wastes 3 bytes for the value.
    It is different for integer vs. float arrays; in this case a % value is indeed packed into 2 bytes.


    I am *not* sue about CBM, but C=64 BASIC does all its arithmetic in
    floating point. That means if you have a line like:

    120 X% = A% * B%

    ...this forces the interpreter to *convert* A% and B% to floating point,
    then do the multiplication using the floating point routines, then
    convert the answer back to an integer and store the answer in X%. Not
    very efficient to do...


    --
    numerist at aquaporin4 dot com

    --- SoupGate-Win32 v1.05
    * Origin: Agency HUB, Dunedin - New Zealand | Fido<>Usenet Gateway (3:770/3)
  • From John H. Guillory@255:255/999 to All on Tue Apr 17 14:46:19 2018
    For clarification, which is faster?
    10 X=INT(64*RND(0)+1)
    or
    10 X%=64*RND(0)+1

    Just guessing, I'd say the second one, or 10 X%=64*RND(0)+1
    because in the first, your converting 64*RNND(0)+1 to an integer, then converting back to a single precision decimal point value.

    --- SoupGate-Win32 v1.05
    * Origin: SpaceSST BBS Usenet <mccarragher.org> Fidonet Gateway (255:255/999)
  • From Janne Johansson@255:255/999 to All on Wed Apr 18 18:35:50 2018
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of repetitions is too hard to figure it out, then the answer isn't really important.

    --- SoupGate-Win32 v1.05
    * Origin: SpaceSST BBS Usenet <mccarragher.org> Fidonet Gateway (255:255/999)
  • From Janne Johansson@255:255/999 to All on Thu Apr 19 10:08:48 2018
    On 2018-04-18 09:37, Shaun Bebbington : Janne Johansson wrote:
    On Wednesday, 18 April 2018 16:41:28 UTC+1, Janne Johansson  wrote:
    On 2018-04-18 05:38, Shaun Bebbington : All wrote:
    Thanks for the hints all. I'll do some bench mark testing or
    whatever :-)

    Please do. If benchmarking with a FOR loop over hundreds or thousands of
    repetitions is too hard to figure it out, then the answer isn't really
    important.

    Hey! Good hint.

    I noticed (after sending of course) that it may have been perceivable as
    a harsh statement, hinting at lazyness or something, I meant more along
    the lines of "if you try 100 loops and can't make out the difference,
    then try 1000 loops then try 10k loops and so on, the difference might
    be so small that its not worth coding your BASIC programs with %
    sprinkled here and there for optimization reasons, but just go for
    normal ordinary readability and simplicity since performance is then
    bound by something else like algorithmic complexity and not the one-time conversions from ints to floats and back".

    If you really need a basic program to run faster, there are a lot of
    compilers that pre-calculate and pre-parse and then make some kind of
    machine language equivalent program out of it which you can run and
    which will be lots faster. If that isn't fast enough still, code
    important parts in ASM directly or at least code it up in CC65 using
    C for some middle ground between compiled BASIC and doing it all in
    ASM yourself.

    --- SoupGate-Win32 v1.05
    * Origin: SpaceSST BBS Usenet <mccarragher.org> Fidonet Gateway (255:255/999)