A quickly expandable routine to test how fast our operators are against each other, for those cases when we want to optimize speed for our programs. (Such as the EllipseFill topic STx posted.)
_TITLE "Expandable Speed Comparison Tool"
CONST LIMIT
= 1 'time allowed for tests (in seconds)
'An expandable list of things to test
DATA "+","-","^","*","/","\","INT"
Int AS _FLOAT 'to store times with integers being tested Float
AS _FLOAT 'to store times with floats being tested Index
AS LONG 'to store the index of the operation, in case we want to sort the results at a later date as we generate more data
DIM Times
(1000) AS Results
'to hold the number of times we can run in a LIMIT
DO UNTIL t$
= "DONE" 'Read in the test results IF t$
<> "DONE" THEN count##
= count##
+ 1: TestString
(count##
) = t$
PRINT "Running tests. Wait"; count##
* 2;
" seconds..."
counter## = 0
counter## = counter## + 1
junk
= RND * 1000000 + 1 'just some random junk to test junk1
= RND * 1000000 + 1 'add one so we never get division by 0 glitches SELECT EVERYCASE TestString
(counter##
) 'We use everystring here so we don't skew results with fast exit CASE comparisons CASE "+": junk
= junk
+ junk1
CASE "-": junk
= junk
- junk1
CASE "^": junk
= junk
^ junk1
CASE "*": junk
= junk
* junk1
CASE "/": junk
= junk
/ junk1
CASE "\": junk
= junk \ junk1
CASE "^.5": junk
= junk
^ 0.5 CASE "x + x": junk
= junk
+ junk
CASE "x * 2": junk
= junk
* 2 Times
(counter##
).
Int = Times
(counter##
).
Int + 1
'Simply copy/paste a duplicate of the SELECT CASE from above to here for _FLOAT comparison speeds
junk
= RND * 1000000 + 1 'just some random junk to test junk1
= RND * 1000000 + 1 'add one so we never get division by 0 glitches SELECT EVERYCASE TestString
(counter##
) 'We use everystring here so we don't skew results with fast exit CASE comparisons CASE "+": junk
= junk
+ junk1
CASE "-": junk
= junk
- junk1
CASE "^": junk
= junk
^ junk1
CASE "*": junk
= junk
* junk1
CASE "/": junk
= junk
/ junk1
CASE "\": junk
= junk \ junk1
CASE "^.5": junk
= junk
^ 0.5 CASE "x + x": junk
= junk
+ junk
CASE "x * 2": junk
= junk
* 2 Times(counter##).Float = Times(counter##).Float + 1
PRINT "Testing speed for: "; TestString
(i
), PRINT "FLOATS:"; Times
(i
).Float
Oddly enough, some of the things which I've always taken for granted now seem to be much different performace-wise than they used to be. (For a quick example, run this under GL and then run it under the old SDL version, if you have it, and watch how drastically the values change.)
In SDL, addition is about 1.5x as fast as multiplication. (3.9 vs 2.5). In the latest GL version of QB64, the two run at comparable speeds, with multiplication being a little faster than addition on my PC.
x + x no longer seems to be any more optimized than x * 2 is. (The speed difference between the two is negligible, at less than 1% difference on my tests.)
x * x, however, still shows a remarkable improvement over x ^ 2. (1.8M vs 0.5M)
Perhaps swapping out the old compiler to the newer compiler which is packaged with QB64 has changed the old rules which I remember so firmly for optimization; I'm not certain. What *is* certain, just from these simple tests, is that I need to start spending more time and testing things more thoroughly to maximize speeds than I used to, for routines which require it.
Also notice that in some cases, speed depends on what type of data you're working with..
Integer Division is faster than Division when dealing with INTEGERS. (Who would've guessed that?!)
Division is faster than Integer Division when dealing with _FLOATS.
(Of course, if you add in an additional INT() command to make the number an integer, then / probably isn't as fast as \ with _FLOATS...)
General rule to remember: Higher numbers relate to faster operations. (After all, it represents the number of times we can perform the operation in a minute.)
Play around with it. Test it with SDL, GL, 32 and 64-bit versions of QB64. See how the values compare on your own machines. Add more test conditions to it and then share them here so we all can make use of them.
And, most importantly,
if you see something wrong with the logic/flow which you think makes the tests invalid, report that issue/concern here. Personally, I think it'd be nice to have a quick little tool to use to see what would be the best operators to use when optimizing for speed as much as possible. ;)