Author Topic: Are Variable Types all that important?  (Read 5351 times)

0 Members and 1 Guest are viewing this topic.

This topic contains a post which is marked as Best Answer. Press here if you would like to see it.

Offline 40wattstudio

  • Newbie
  • Posts: 82
    • View Profile
    • 40wattstudio
Are Variable Types all that important?
« on: October 02, 2020, 03:53:08 pm »
So I was reading this interesting QB64 page:
https://www.qb64.org/wiki/Variable_Types

And it got me to thinking, I almost always have used Integers for all my numerical needs. Besides holding a greater range of values, are there any practical advantages for using the right Variable types?

For example, let's say I'm making a program that uses 400 variables that will only ever be 0 or 1. According to the chart, the _BIT would be the best fit. But if I used DOUBLE to hold all those 0s and 1s, could that be detrimental in any way? Like a larger file size? Is the time to complete math operations dependent on what variable type is used?

Just trying to see if it's worth my time declaring the "right" variable types . . . or if it even makes much of a difference at all.


Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Are Variable Types all that important?
« Reply #1 on: October 02, 2020, 04:09:06 pm »
The top limits of variable types matter, integer has a limit of +/- 32000+ if your file has 50,000 records you don't want an integer to track record numbers.

Some numbers need the decimal part and others do not. The best Type for Color with Alpha transparencies is _UNSIGNED LONG

_DOUBLE or _FLOAT will give greatest range with highest precision but costs more in variable size and speed because more bits to process but will you notice? depends on how intense your calculations go.

_INTEGER64, INTEGER accuracy with highest range.

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Are Variable Types all that important?
« Reply #2 on: October 02, 2020, 04:22:58 pm »
It is also necessary to mention the fundamental difference between QB4.5 and QB64. When the allowed limit of the data type (65535 for the _UNSIGNED INTEGER type) is exceeded, an overflow error is declared in QB4.5. In QB64 this does not happen, the value is automatically flipped back to 0 for the number 65536. I would not be enough with the INTEGER type in any case. Whether it is addressing the offset in memory or the byte position in the file, I always very easily exceed the maximum value of this type. It is also necessary to know that if you need really lightning fast calculations, then it is always the fastest when you use the same data types.
« Last Edit: October 02, 2020, 04:25:43 pm by Petr »

Offline 40wattstudio

  • Newbie
  • Posts: 82
    • View Profile
    • 40wattstudio
Re: Are Variable Types all that important?
« Reply #3 on: October 02, 2020, 04:28:45 pm »
Yeah I found out about Integers the hard way . . . I had a score counter and after it reached 32,767 it went negative. Pretty amusing but had me puzzled for a while.

Here's how I've been trying to visualize data types:

DOUBLE, because it can hold so much, is like a cardboard box the size of a parking lot. To me, using a DOUBLE to "hold" variables that are only going to be small (like Boolean 0s and 1s) is a waste of space and not very practical. In that table referenced earlier, I see there's a column titled "Size in Bytes". Now my question is this: Is that the size of just the empty DOUBLE container with nothing in it . . . like if you wrote a program that only had this line of code . . .

DIM A AS DOUBLE.

Or does Size in Bytes only apply once something has been put in the DOUBLE container, like this . . . ?

DIM A AS DOUBLE
A = 200000000000000000

Offline Petr

  • Forum Resident
  • Posts: 1720
  • The best code is the DNA of the hops.
    • View Profile
Re: Are Variable Types all that important?
« Reply #4 on: October 02, 2020, 04:35:43 pm »
I assume that if you declare a data type with a DIM statement, the compiler reserves the required number of bytes in memory for it. The same thing happens when is writed this type to a binary file, there you calculate according to the data type at which byte position which data variable starts.

FellippeHeitor

  • Guest
Re: Are Variable Types all that important?
« Reply #5 on: October 02, 2020, 04:51:54 pm »
Also: don’t use _BIT. Use _BYTE to avoid the overhead. And trouble.

Offline 40wattstudio

  • Newbie
  • Posts: 82
    • View Profile
    • 40wattstudio
Re: Are Variable Types all that important?
« Reply #6 on: October 02, 2020, 05:27:09 pm »
It is also necessary to know that if you need really lightning fast calculations, then it is always the fastest when you use the same data types.

Good to know! I wasn't aware of that one.

Marked as best answer by 40wattstudio on October 03, 2020, 04:56:34 pm

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Are Variable Types all that important?
« Reply #7 on: October 02, 2020, 07:00:58 pm »
In regards to variable types:

_BIT should *only* be used when you’re dealing with a large array for bit packing.  If you don’t know what that is, or why you’d use it, ignore that _BIT even exists.  It’s slow, has overhead, and will only be a detriment in your programs performance.  If you’re really serious to learn about it, start another topic and I’ll write you a book on it.  Otherwise, just remember: Unless you’re bit packing an array, DON’T worry with using _BIT.  Use _BYTE instead.



When dealing with RGBA color values, either use _UNSIGNED LONG, or _INTEGER64 to store those values.  SINGLE is the default variable type for QB64, but it’s not capable of holding all the values in a 32-bit color palette.  LONG *may* seem to work for you, but you’re playing with fire if you do.

_RGBA is &HFFFFFFFF. 
&HFFFFFFFF in signed long values is: -2,147,483,648
&HFFFFFFFF in unsigned long values is: 4,294,967,295

Both a LONG and an UNSIGNED LONG will hold those 4 bytes for RGBA color values, but if you mix the types and compare them, they give vast different results.

-2,147,483,648  and 4,294,967,295 both in HEX are represented as FFFFFFFF, depending on whether you have a signed, or unsigned variable type.  The difference for COLOR is nothing at all, but for an IF statement, those two values are vastly different.  Since POINT and other QB64 commands return those 4-bytes as an UNSIGNED LONG, it’s best if you default to using unsigned longs as well.

A quick demo is here:

Code: [Select]
SCREEN _NEWIMAGE(640, 480, 32)
DIM L AS LONG, U AS _UNSIGNED LONG
L = _RGB32(255, 255, 255)
U = _RGB32(255, 255, 255)

PSET (0,0), L
PSET (1,1), U

IF POINT(0,0) = L THEN PRINT “POINT 0,0 is a match”
IF POINT(1,1) = U THEN PRINT “POINT 1,1 is a match”



Generally speaking, use of all LONGs (if possible) will perform faster on most modern systems than other types.  They add faster, process faster, and are generally more efficient at a register level.

_BIT is a niche use type, and slow to use.  Think of it basically as a ZIP file.  Compressing a file saves disk space, but it harms performance as you have to unzip it to access its data before using it.  That’s the exact same thing _BIT does.  Generally, just forget it exists.

_BYTE and INTEGER both saves memory, if you only need values in that range, but they tend to be a little slower in processing than LONG.  (At least, on my system, they almost always are.)

_INTEGER64 uses twice the memory as LONG, so unless you’re just dealing with super large values, ignore it. 

SINGLE and DOUBLE, I tend to ignore, in most cases.  _FLOAT uses a ton more memory, but it tends to process faster than the other real types.  Since I’m generally only using real values in repetitive loops, and often in complex math operations, I tend to just use _FLOAT for the handful of real variables I need.

My general programming style is basically:
_DEFINE A-Z AS LONG
Color variables are dimmed as _UNSIGNED LONG
Math and fractional values are dimmed as _FLOAT

For anything else, I generally need to have a good reason to incorporate them into my programs.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Are Variable Types all that important?
« Reply #8 on: October 02, 2020, 07:08:12 pm »
I assume that if you declare a data type with a DIM statement, the compiler reserves the required number of bytes in memory for it. The same thing happens when is writed this type to a binary file, there you calculate according to the data type at which byte position which data variable starts.

Actually, I don’t think it does, if my memory is correct.  I think we only create those blocks in memory, once we access them.   Test this:

Code: [Select]
DIM b(1000000000) AS _BYTE
Print “Pre-use”
SLEEP
b(1000000000) = 123
PRINT “Post-Use”
SLEEP

Run that and watch memory usage in task manager.  I’m thinking you won’t see program memory jump to 1GB, until after you pass that first SLEEP statement and actually haveto use that memory. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline luke

  • Administrator
  • Seasoned Forum Regular
  • Posts: 324
    • View Profile
Re: Are Variable Types all that important?
« Reply #9 on: October 02, 2020, 09:41:17 pm »
Actually, I don’t think it does, if my memory is correct.  I think we only create those blocks in memory, once we access them.   Test this:

Code: [Select]
DIM b(1000000000) AS _BYTE
Print “Pre-use”
SLEEP
b(1000000000) = 123
PRINT “Post-Use”
SLEEP

Run that and watch memory usage in task manager.  I’m thinking you won’t see program memory jump to 1GB, until after you pass that first SLEEP statement and actually haveto use that memory.
I haven't checked, but I suspect you'll probably see it jump straight away because it has to initialise all the values to 0.

My variable usage is basically the same as Steve's (possibly the first time we agree on something?!) though I tend to go for DOUBLE instead of _FLOAT because the symbol is one character instead of two and I'm lazy.

Offline 40wattstudio

  • Newbie
  • Posts: 82
    • View Profile
    • 40wattstudio
Re: Are Variable Types all that important?
« Reply #10 on: October 03, 2020, 09:01:07 pm »
_BIT is a niche use type, and slow to use.  Think of it basically as a ZIP file.  Compressing a file saves disk space, but it harms performance as you have to unzip it to access its data before using it.  That’s the exact same thing _BIT does.  Generally, just forget it exists.

Good analogy! Describing it that way, yeah, _BIT sounds like a terrible idea if you have to "unzip" it all the time. I hadn't thought of that.
Thanks for the detailed feedback!

Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: Are Variable Types all that important?
« Reply #11 on: October 03, 2020, 11:42:39 pm »
It doesn't make a lot of sense to me that LONG would be faster then INTEGER, but  SMcNeill
is  right as usual (always?).   Yee-haw, another performance boost for my chess program.
« Last Edit: October 03, 2020, 11:44:34 pm by Richard Frost »
It works better if you plug it in.