(06-27-2025, 08:43 AM)Elzaimer Wrote: ..... So, for me, I had to use INTEGER (only 2 bytes, so fast in my mind).....
That is a
very common, but very wrong, misunderstanding/mistake.
As already explained by others, the 'standard' rule is: choose the type which is the
same as the native register/type size of your CPU.
For 32 bit CPUs that would be anything with 32 bit = LONG (and not INTEGER like it has been used in a gazzilion programs)
For 64 bit CPUs that would be anything with 64 bit = _INTEGER64 in case of QB64.
HOWEVER... As you can read in all the posts, it HIGHLY depends on other things too:
- your specific CPU and its capabilities
but also:
- WHAT you want to calculate,
- HOW you're going to calculate,
- is it optimizable by compiler,
- is it optimizable by CPU during processing (branch prediction, pipelining),
- does your CPU has co-processor, FPU, special optimizations, ...
(06-27-2025, 05:44 PM)madscijr Wrote: (06-27-2025, 01:45 PM)SMcNeill Wrote: Integer Division (the \ division) is much faster than taking the integer value of normal division.......
No kidding? This is very very useful to know for any QB64 / QB64PE programmer, thanks for sharing.
Do we by chance have a FAQ anywhere with these little bits of wisdom collected together?
To be honest, this is explained literally in almost ANY (good) basic programming course/manual/etc.
(but it is true that it is often overlooked)
(06-27-2025, 05:44 PM)madscijr Wrote: Hmm... I wonder if there is a way to check the hardware from code, so your program can choose the faster method at runtime, depending on the FPU type detected?
AFAIK, no there is not. And even if there was, it would HIGHLY depend on WHAT you want to calculate and HOW you do it.
Because it also depends on how the compiler behaves and if it can optimize the code or not.
This includes dependency on how good your processor is with pipelining (is kind of like parallel processing) and branch predicting (which can vary very very wildly depending on processor).
Eg: you can use the theoretical 'faster' TYPE, but code a bad/slow routine for optimization. And thus it would be outperformed by using a theoretical 'slower' TYPE but coded in such way that it is optimized by the compiler and/or CPU.
So, I think the best way to do something like that, is writing a small 'test-routine' for each and every TYPE you'd wanna test, and check its timings at the beginning of your program. Then, depending on that timing, you run the proper dedicated routines with the appropiate types.
BUT, this also implies that you can
NOT use pre-compiler statements to include/exclude routines; because you need to include ALL the different routines in your code since it highly depends on compiler AND cpu behavior. Removing them with conditional (pre-)compiling would defeat the whole purpose.
Also, in this case, one size does
not fit all! That is: your test routines need to mimic the actual big calculation you wanna do in the main program. Otherwise, it would also defeat the purpose of the tests.
(eg: I could test all TYPES with integer division by powers of two, and in the main program I do non-power of two divisions, multiplications and what not..... The compiler and/or cpu would greatly optimize the test routines (because of 'powers of two'), but can't optimize the main program. So all test timings would be very off)
(06-28-2025, 12:13 AM)ahenry3068 Wrote: Also when using Integer's the NATIVE REGISTER SIZE is going to be fastest. On modern systems that _INTEGER64 !! Not Integer or Even Long. !!!
Yes, this!!!11!!
And for as long as I know, this has always been the case!
And for as long as I know, people have always been 'confused' by that. lol
I can't count the amount of code I've seen where people declare their variables as 'INTEGER', thinking it would be faster/fasted, while in fact it has been the 'LONG' type since like almost forever (on 32-bit machines)....
Changing INTEGER to LONG is almost without exception the number one thing I always did when reviewing code (also fixed quite a lot of possible overflow problems).
As for
floating point divisions:
Yep, it all depends on your (integrated or external) FPU.
It used to be that FPUs were rare and even if they existed, they were slow.
But, this has been changed since decades.
So, to know what is faster all depends on WHAT and HOW you calculate stuff.
For example,
if you divide by powers of two, do NOT use integer division either! Instead use 'shift' operator, if the language supports it. And/or use a decent compiler which will recognize divisions by a power of two as a 'shift'. But luckily, as it happens today, almost all common compilers these days do recognize such calculations and convert them to shifts 'under the hood'.
As for
integer divisions:
Guys, do NOT call or confuse
INT(x/y) as an
"integer division". It is absolutely not! It is a
floating point division (where the result is casted to an integer). That is very different than a
real integer division using the integer division operator: '\' (notice this is backslash, not a forward slash!).
PS: Another interesting dependency in all of this speed-testing and comparing bussiness:
Microsoft Windows + all bad behaving programs (like Chrome!).
In very short: your computer has a special timer, which is used to initiate interrupts.
The frequency of this timer can be set by any program (or Windows itself) and is often done so.
However, it is quite often set to a too high frequency and more than often not set back.
As such interrupts will be firing far more than needed and your CPU is increasingly busy.
This WILL and DOES slow down your computer, and in some cases significantly (up to 5% in some cases).
More about that
here.
Point is: even on the same system, you can have very different results in speed tests. Great care should be taken when speed testing on modern systems... actually, far more than on older systems.