Posts: 234
Threads: 17
Joined: Apr 2022
Reputation:
4
05-18-2022, 10:59 AM
(This post was last modified: 05-18-2022, 12:54 PM by Coolman.)
CRC-32 : I got this code from the site rosettacode. I added some code to test the processing speed with QB64 compiled with the O3 option and the original version.
6.7x seconds : program compiled with qb64 -O3
17.6x seconds : program compiled with original qb64
here the speed gain is clearly visible.
Code: (Select All) ' Rosetta Code - CRC-32
Dim tab$(19)
tab$(0) = "malevolently malevolous malexecution malfeasance malfeasant malfeasantly malfeasants malfeasor overwon"
tab$(1) = "malfed malformation malformations malformed malfortune malfunction malfunctioned malfunctioning overwood"
tab$(2) = "malgovernment nonemotionalism nonemotionally verwing overwinning overwinter overwintered overwintering"
tab$(3) = "nonemanating nonemancipation nonemancipative nonembarkation nonembellished nonembellishing overwiped"
tab$(4) = "nonembellishment nonembezzlement nonembryonal nonembryonic nonembryonically nonemendable overwithered"
tab$(5) = "nonemendation nonemergence nonemergent nonemigrant nonemigration nonemission nonemotional overwomanize"
tab$(6) = "overwisdom overwise overwisely overwoman overwomanly overwooded overwoody overword overwords overwore"
tab$(7) = "overwork segreant segregable segregant segregate segregated segregatedly segregatedness segregateness"
tab$(8) = "segregates segregating segregation segregational segregationist segregationists segregative segregator"
tab$(9) = "teleostean teleostei teleosteous teleostomate teleostome teleostomi teleostomian teleostomous teleosts"
tab$(10) = "teleotemporal teleotrocha teleozoic teleozoon telepath telepathy telepathic telepathically telepathies"
tab$(11) = "telepathist telepathize nffroze unfibbed unfibbing unfiber unfibered unfibred unfibrous unfibrously"
tab$(12) = "unfickle unfictitious unfictitiously unfictitiousness unfidelity unfidgeting unfiducial unfielded"
tab$(13) = "unfiend unfiendlike unfierce unfiercely unfiery unfight unfightable unfighting unfigurable unfigured"
tab$(14) = "zulus zumatic zumbooruk zuni zunian zunyite zunis zupanate zurich zurlite zutugil zuurveldt zuza"
tab$(15) = "zwanziger zwieback zwiebacks zwieselite zwinglian zwinglianism zwinglianist zwitter zwitterion"
tab$(16) = "zwitterionic cognovits cogon cogonal cogons cogovernment cogovernor cogracious cograil cogrediency"
tab$(17) = "cogredient cogroad cogs cogswellia coguarantor coguardian cogue cogway cogways cogware cogweel"
tab$(18) = "cogweels cogwheel cogwheels xiphistna xiphisura xiphisuran xiphiura xiphius xiphocostal xiphodynia"
tab$(19) = "xiphodon xiphodontidae xiphoid xyphoid xiphoidal xiphoidian xiphoids xiphopagic xiphopagous xiphopagus"
Color 7: Print "Wait..."
Color 2: Print: Print " generation of test string..."
Dim tabch$(15)
For boucle% = 1 To 15
chaine$ = ""
For i = 1 To 10000
chaine$ = chaine$ + tab$(Rnd * 19)
Next i
tabch$(boucle%) = chaine$
Next boucle%
Dim hash$(15)
Color 3: Print: Print " crc calculation 100 times in : ";
start = Timer(.001)
For nbr% = 1 To 100
For boucle% = 1 To 15
chaine$ = tabch$(boucle%)
hash$(boucle%) = Hex$(crc32(chaine$))
Next boucle%
Next nbr%
Print Timer(.001) - start; "seconds"
Color 14: Print
For boucle% = 1 To 15: Print " "; hash$(boucle%): Next boucle%
Color 7
End
Function crc32~& (buf As String)
Static table(255) As _Unsigned Long
Static have_table As _Byte
Dim crc As _Unsigned Long, k As _Unsigned Long
Dim i As Long, j As Long
If have_table = 0 Then
For i = 0 To 255
k = i
For j = 0 To 7
If (k And 1) Then
k = _SHR(k, 1)
k = k Xor &HEDB88320
Else
k = _SHR(k, 1)
End If
table(i) = k
Next
Next
have_table = -1
End If
crc = Not crc ' crc = &Hffffffff
For i = 1 To Len(buf)
crc = (_SHR(crc, 8)) Xor table((crc And &HFF) Xor Asc(buf, i))
Next
crc32~& = Not crc
End Function
Posts: 529
Threads: 67
Joined: Apr 2022
Reputation:
11
I can see you are busy running tests and comparing the results of the different compiler options.
Do you think you can take all this knowledge gained and put it into an FAQ or "best practices" doc of some kind?
This could benefit all the QB64 users who would be interested in learning to compile their programs optimized for speed...
Posts: 234
Threads: 17
Joined: Apr 2022
Reputation:
4
(05-19-2022, 02:18 PM)madscijr Wrote: I can see you are busy running tests and comparing the results of the different compiler options.
Do you think you can take all this knowledge gained and put it into an FAQ or "best practices" doc of some kind?
This could benefit all the QB64 users who would be interested in learning to compile their programs optimized for speed...
Hi @madscijr. That's a good idea. I'll think about it.
Posts: 234
Threads: 17
Joined: Apr 2022
Reputation:
4
i discover day by day interesting features in qb64. today it's about _Deflate (compression) and _Inflate (decompression) functions. i wanted to test them. here is the result :
program compiled with qb64 -O3 :
Function _Deflate : 10.1x seconds
Function _Inflate : 1.2x seconds
program compiled with original qb64 :
Function _Deflate : 10.1x seconds
Function _Inflate : 1.2x seconds
the result of the comparison is almost zero in terms of processing speed. i examined the compilation directives of the original version of qb64. it turns out that the compression and decompression module is compiled with the -O3 option. nothing surprising to this result.
on character strings, compression is very efficient and decompression is very fast. this should allow to reduce efficiently the disk space occupied by text data...
Code: (Select All) Dim tab$(19)
tab$(0) = "malevolently malevolous malexecution malfeasance malfeasant malfeasantly malfeasants malfeasor overwon"
tab$(1) = "malfed malformation malformations malformed malfortune malfunction malfunctioned malfunctioning overwood"
tab$(2) = "malgovernment nonemotionalism nonemotionally verwing overwinning overwinter overwintered overwintering"
tab$(3) = "nonemanating nonemancipation nonemancipative nonembarkation nonembellished nonembellishing overwiped"
tab$(4) = "nonembellishment nonembezzlement nonembryonal nonembryonic nonembryonically nonemendable overwithered"
tab$(5) = "nonemendation nonemergence nonemergent nonemigrant nonemigration nonemission nonemotional overwomanize"
tab$(6) = "overwisdom overwise overwisely overwoman overwomanly overwooded overwoody overword overwords overwore"
tab$(7) = "overwork segreant segregable segregant segregate segregated segregatedly segregatedness segregateness"
tab$(8) = "segregates segregating segregation segregational segregationist segregationists segregative segregator"
tab$(9) = "teleostean teleostei teleosteous teleostomate teleostome teleostomi teleostomian teleostomous teleosts"
tab$(10) = "teleotemporal teleotrocha teleozoic teleozoon telepath telepathy telepathic telepathically telepathies"
tab$(11) = "telepathist telepathize nffroze unfibbed unfibbing unfiber unfibered unfibred unfibrous unfibrously"
tab$(12) = "unfickle unfictitious unfictitiously unfictitiousness unfidelity unfidgeting unfiducial unfielded"
tab$(13) = "unfiend unfiendlike unfierce unfiercely unfiery unfight unfightable unfighting unfigurable unfigured"
tab$(14) = "zulus zumatic zumbooruk zuni zunian zunyite zunis zupanate zurich zurlite zutugil zuurveldt zuza"
tab$(15) = "zwanziger zwieback zwiebacks zwieselite zwinglian zwinglianism zwinglianist zwitter zwitterion"
tab$(16) = "zwitterionic cognovits cogon cogonal cogons cogovernment cogovernor cogracious cograil cogrediency"
tab$(17) = "cogredient cogroad cogs cogswellia coguarantor coguardian cogue cogway cogways cogware cogweel"
tab$(18) = "cogweels cogwheel cogwheels xiphistna xiphisura xiphisuran xiphiura xiphius xiphocostal xiphodynia"
tab$(19) = "xiphodon xiphodontidae xiphoid xyphoid xiphoidal xiphoidian xiphoids xiphopagic xiphopagous xiphopagus"
Color 7: Print "Wait..."
Color 2: Print: Print " generation of test string..."
Dim tabch$(15)
For boucle% = 1 To 15
chaine$ = ""
For nbr% = 1 To 10000
chaine$ = chaine$ + tab$(Rnd * 19)
Next nbr%
tabch$(boucle%) = chaine$
Next boucle%
Dim chcompress$(15)
Color 3: Print: Print " compress string 100 times in : ";
start = Timer(.001)
For nbr% = 1 To 100
For boucle% = 1 To 15
chaine$ = tabch$(boucle%)
chcompress$(boucle%) = _Deflate$(chaine$)
Next boucle%
Next nbr%
Print Timer(.001) - start; "seconds"
Color 14: Print
For boucle% = 1 To 15
Print " len string original : "; Len(tabch$(boucle%)); " --> Compressed : "; Len(chcompress$(boucle%))
Next boucle%
Color 3: Print: Print " Decompress string 100 times in : ";
start = Timer(.001)
For nbr% = 1 To 100
For boucle% = 1 To 15
chaine$ = chcompress$(boucle%)
tabch$(boucle%) = _Inflate$(chaine$)
Next boucle%
Next nbr%
Print Timer(.001) - start; "seconds"
Color 7
End
Posts: 529
Threads: 67
Joined: Apr 2022
Reputation:
11
(05-19-2022, 06:13 PM)Coolman Wrote: (05-19-2022, 02:18 PM)madscijr Wrote: I can see you are busy running tests and comparing the results of the different compiler options.
Do you think you can take all this knowledge gained and put it into an FAQ or "best practices" doc of some kind?
This could benefit all the QB64 users who would be interested in learning to compile their programs optimized for speed...
Hi @madscijr. That's a good idea. I'll think about it.
How did all these tests turn out?
Any final results?
Posts: 234
Threads: 17
Joined: Apr 2022
Reputation:
4
hello @madscijr, i think i've done the trick. compiled with option O3, qb64 is much faster than the original version in calculations, sorting algorithms, string manipulations. the speed gain is very important. the console programs i've made for personal use are quite efficient although not as fast as freebasic. qb64 allows to develop very quickly like quickbasic. it's a definite advantage. you can concentrate on the essential. i didn't notice any visible problem. it would be necessary to make more tests to validate the compilation in O3 and eventually to propose an optimized version of qb64. but this decision is up to the maintainers of qb64.
frankly, I had not considered using qb64 at the beginning. I tested many very interesting basic interpreter, I thought that the speed of development and the instantaneous execution of the programs is an important criterion, finally the speed of execution is more important when it is necessary to make many treatments. I will thus use qb64 intensively. I would continue to use freebasic equally.
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
"frankly, I had not considered using qb64 at the beginning. I tested many very interesting basic interpreter, I thought that the speed of development and the instantaneous execution of the programs is an important criterion, finally the speed of execution is more important when it is necessary to make many treatments. I will thus use qb64 intensively. I would continue to use freebasic equally."
It does take some practice to appreciate the full scope of what QB64 IDE offers. What you lose in the little bit of compile time before execution of new code is more than made up for avoiding typo's and syntax errors, fast lookup of keywords and a host of things you wont get from a third party editor IMHO. Don't look at compile time, execution time is way more important because you only compile once to make an exe. I would say that development time is at least as important as execution time (maybe more so when turning one proggie after another :-)) It use to be space for memory and length of programs but now it's about time, humans' more so than computers.
b = b + ...
Posts: 529
Threads: 67
Joined: Apr 2022
Reputation:
11
(06-08-2022, 03:11 PM)bplus Wrote: It use to be space for memory and length of programs but now it's about time, humans' more so than computers.
I wholeheartedly agree!
Let the machines do the work - saving humans time was always the promise and the whole point of using computers to begin with ;-)
Posts: 336
Threads: 24
Joined: Apr 2022
Reputation:
19
just for testing
Code: (Select All) _Title "n-body"
'http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=gcc&id=1
' The Computer Language Benchmarks Game
' http://benchmarksgame.alioth.debian.org/
' contributed by Christoph Bauer
'
' translated to QB64 by Jack
' modified a bit to avoid using pointer to array
declare FUNCTION main# (n AS LONG)
Print Str$(main(50000000)) + " seconds"
End
Const pi = 3.141592653589793
Const solar_mass = (4 * pi) * pi
Const days_per_year = 365.24
Type planet
x As Double
y As Double
z As Double
vx As Double
vy As Double
vz As Double
mass As Double
End Type
Sub advance (nbodies As Long, bodies() As planet, dt As Double)
Dim i As Long, j As Long
Dim dx As Double, dy As Double, dz As Double, distance As Double, mag As Double
For i = 0 To nbodies - 1
For j = i + 1 To nbodies - 1
dx = bodies(i).x - bodies(j).x
dy = bodies(i).y - bodies(j).y
dz = bodies(i).z - bodies(j).z
distance = Sqr(((dx * dx) + (dy * dy)) + (dz * dz))
mag = dt / ((distance * distance) * distance)
bodies(i).vx = bodies(i).vx - (dx * bodies(j).mass) * mag
bodies(i).vy = bodies(i).vy - (dy * bodies(j).mass) * mag
bodies(i).vz = bodies(i).vz - (dz * bodies(j).mass) * mag
bodies(j).vx = bodies(j).vx + (dx * bodies(i).mass) * mag
bodies(j).vy = bodies(j).vy + (dy * bodies(i).mass) * mag
bodies(j).vz = bodies(j).vz + (dz * bodies(i).mass) * mag
Next
Next
For i = 0 To nbodies - 1
bodies(i).x = bodies(i).x + dt * bodies(i).vx
bodies(i).y = bodies(i).y + dt * bodies(i).vy
bodies(i).z = bodies(i).z + dt * bodies(i).vz
Next
End Sub
Function energy# (nbodies As Long, bodies() As planet)
Dim i As Long, j As Long
Dim e As Double, dx As Double, dy As Double, dz As Double, distance As Double, mag As Double
e = 0.0
For i = 0 To nbodies - 1
e = e + (0.5 * bodies(i).mass) * (((bodies(i).vx * bodies(i).vx) + (bodies(i).vy * bodies(i).vy)) + (bodies(i).vz * bodies(i).vz))
For j = i + 1 To nbodies - 1
dx = bodies(i).x - bodies(j).x
dy = bodies(i).y - bodies(j).y
dz = bodies(i).z - bodies(j).z
distance = Sqr(((dx * dx) + (dy * dy)) + (dz * dz))
e = e - (bodies(i).mass * bodies(j).mass) / distance
Next
Next
energy# = e
End Function
Sub offset_momentum (nbody As Long, bodies() As planet)
Dim px As Double, py As Double, pz As Double
Dim I As Long
For I = 0 To nbody - 1
px = px + bodies(I).vx * bodies(I).mass
py = py + bodies(I).vy * bodies(I).mass
pz = pz + bodies(I).vz * bodies(I).mass
Next
bodies(0).vx = (-px) / ((4 * pi) * pi)
bodies(0).vy = (-py) / ((4 * pi) * pi)
bodies(0).vz = (-pz) / ((4 * pi) * pi)
End Sub
Function main# (n As Long)
Const NBODIES = 5
Dim bodies(0 To 4) As planet
bodies(0).x = 0: bodies(0).y = 0: bodies(0).z = 0: bodies(0).vx = 0: bodies(0).vy = 0: bodies(0).vz = 0: bodies(0).mass = (4 * pi) * pi
bodies(1).x = 4.84143144246472090D+00: bodies(1).y = -1.16032004402742839D+00: bodies(1).z = -1.03622044471123109D-01: bodies(1).vx = 1.66007664274403694D-03 * days_per_year: bodies(1).vy = 7.69901118419740425D-03 * days_per_year: bodies(1).vz = (-6.90460016972063023D-05) * days_per_year: bodies(1).mass = 9.54791938424326609D-04 * ((4 * pi) * pi)
bodies(2).x = 8.34336671824457987D+00: bodies(2).y = 4.12479856412430479D+00: bodies(2).z = -4.03523417114321381D-01: bodies(2).vx = (-2.76742510726862411D-03) * days_per_year: bodies(2).vy = 4.99852801234917238D-03 * days_per_year: bodies(2).vz = 2.30417297573763929D-05 * days_per_year: bodies(2).mass = 2.85885980666130812D-04 * ((4 * pi) * pi)
bodies(3).x = 1.28943695621391310D+01: bodies(3).y = -1.51111514016986312D+01: bodies(3).z = -2.23307578892655734D-01: bodies(3).vx = 2.96460137564761618D-03 * days_per_year: bodies(3).vy = 2.37847173959480950D-03 * days_per_year: bodies(3).vz = (-2.96589568540237556D-05) * days_per_year: bodies(3).mass = 4.36624404335156298D-05 * ((4 * pi) * pi)
bodies(4).x = 1.53796971148509165D+01: bodies(4).y = -2.59193146099879641D+01: bodies(4).z = 1.79258772950371181D-01: bodies(4).vx = 2.68067772490389322D-03 * days_per_year: bodies(4).vy = 1.62824170038242295D-03 * days_per_year: bodies(4).vz = (-9.51592254519715870D-05) * days_per_year: bodies(4).mass = 5.15138902046611451D-05 * ((4 * pi) * pi)
Dim i As Long
Dim t As Double
t = Timer
Call offset_momentum(NBODIES, bodies())
Print Using "##.#########"; energy#(NBODIES, bodies())
For i = 1 To n
Call advance(NBODIES, bodies(), 0.01)
Next
Print Using "##.#########"; energy#(NBODIES, bodies())
main# = Timer - t
End Function
Posts: 234
Threads: 17
Joined: Apr 2022
Reputation:
4
(06-10-2022, 02:41 AM)Jack Wrote: just for testing
Code: (Select All) _Title "n-body"
'http://benchmarksgame.alioth.debian.org/u64q/program.php?test=nbody&lang=gcc&id=1
' The Computer Language Benchmarks Game
' http://benchmarksgame.alioth.debian.org/
' contributed by Christoph Bauer
'
' translated to QB64 by Jack
' modified a bit to avoid using pointer to array
declare FUNCTION main# (n AS LONG)
Print Str$(main(50000000)) + " seconds"
End
Const pi = 3.141592653589793
Const solar_mass = (4 * pi) * pi
Const days_per_year = 365.24
Type planet
x As Double
y As Double
z As Double
vx As Double
vy As Double
vz As Double
mass As Double
End Type
Sub advance (nbodies As Long, bodies() As planet, dt As Double)
Dim i As Long, j As Long
Dim dx As Double, dy As Double, dz As Double, distance As Double, mag As Double
For i = 0 To nbodies - 1
For j = i + 1 To nbodies - 1
dx = bodies(i).x - bodies(j).x
dy = bodies(i).y - bodies(j).y
dz = bodies(i).z - bodies(j).z
distance = Sqr(((dx * dx) + (dy * dy)) + (dz * dz))
mag = dt / ((distance * distance) * distance)
bodies(i).vx = bodies(i).vx - (dx * bodies(j).mass) * mag
bodies(i).vy = bodies(i).vy - (dy * bodies(j).mass) * mag
bodies(i).vz = bodies(i).vz - (dz * bodies(j).mass) * mag
bodies(j).vx = bodies(j).vx + (dx * bodies(i).mass) * mag
bodies(j).vy = bodies(j).vy + (dy * bodies(i).mass) * mag
bodies(j).vz = bodies(j).vz + (dz * bodies(i).mass) * mag
Next
Next
For i = 0 To nbodies - 1
bodies(i).x = bodies(i).x + dt * bodies(i).vx
bodies(i).y = bodies(i).y + dt * bodies(i).vy
bodies(i).z = bodies(i).z + dt * bodies(i).vz
Next
End Sub
Function energy# (nbodies As Long, bodies() As planet)
Dim i As Long, j As Long
Dim e As Double, dx As Double, dy As Double, dz As Double, distance As Double, mag As Double
e = 0.0
For i = 0 To nbodies - 1
e = e + (0.5 * bodies(i).mass) * (((bodies(i).vx * bodies(i).vx) + (bodies(i).vy * bodies(i).vy)) + (bodies(i).vz * bodies(i).vz))
For j = i + 1 To nbodies - 1
dx = bodies(i).x - bodies(j).x
dy = bodies(i).y - bodies(j).y
dz = bodies(i).z - bodies(j).z
distance = Sqr(((dx * dx) + (dy * dy)) + (dz * dz))
e = e - (bodies(i).mass * bodies(j).mass) / distance
Next
Next
energy# = e
End Function
Sub offset_momentum (nbody As Long, bodies() As planet)
Dim px As Double, py As Double, pz As Double
Dim I As Long
For I = 0 To nbody - 1
px = px + bodies(I).vx * bodies(I).mass
py = py + bodies(I).vy * bodies(I).mass
pz = pz + bodies(I).vz * bodies(I).mass
Next
bodies(0).vx = (-px) / ((4 * pi) * pi)
bodies(0).vy = (-py) / ((4 * pi) * pi)
bodies(0).vz = (-pz) / ((4 * pi) * pi)
End Sub
Function main# (n As Long)
Const NBODIES = 5
Dim bodies(0 To 4) As planet
bodies(0).x = 0: bodies(0).y = 0: bodies(0).z = 0: bodies(0).vx = 0: bodies(0).vy = 0: bodies(0).vz = 0: bodies(0).mass = (4 * pi) * pi
bodies(1).x = 4.84143144246472090D+00: bodies(1).y = -1.16032004402742839D+00: bodies(1).z = -1.03622044471123109D-01: bodies(1).vx = 1.66007664274403694D-03 * days_per_year: bodies(1).vy = 7.69901118419740425D-03 * days_per_year: bodies(1).vz = (-6.90460016972063023D-05) * days_per_year: bodies(1).mass = 9.54791938424326609D-04 * ((4 * pi) * pi)
bodies(2).x = 8.34336671824457987D+00: bodies(2).y = 4.12479856412430479D+00: bodies(2).z = -4.03523417114321381D-01: bodies(2).vx = (-2.76742510726862411D-03) * days_per_year: bodies(2).vy = 4.99852801234917238D-03 * days_per_year: bodies(2).vz = 2.30417297573763929D-05 * days_per_year: bodies(2).mass = 2.85885980666130812D-04 * ((4 * pi) * pi)
bodies(3).x = 1.28943695621391310D+01: bodies(3).y = -1.51111514016986312D+01: bodies(3).z = -2.23307578892655734D-01: bodies(3).vx = 2.96460137564761618D-03 * days_per_year: bodies(3).vy = 2.37847173959480950D-03 * days_per_year: bodies(3).vz = (-2.96589568540237556D-05) * days_per_year: bodies(3).mass = 4.36624404335156298D-05 * ((4 * pi) * pi)
bodies(4).x = 1.53796971148509165D+01: bodies(4).y = -2.59193146099879641D+01: bodies(4).z = 1.79258772950371181D-01: bodies(4).vx = 2.68067772490389322D-03 * days_per_year: bodies(4).vy = 1.62824170038242295D-03 * days_per_year: bodies(4).vz = (-9.51592254519715870D-05) * days_per_year: bodies(4).mass = 5.15138902046611451D-05 * ((4 * pi) * pi)
Dim i As Long
Dim t As Double
t = Timer
Call offset_momentum(NBODIES, bodies())
Print Using "##.#########"; energy#(NBODIES, bodies())
For i = 1 To n
Call advance(NBODIES, bodies(), 0.01)
Next
Print Using "##.#########"; energy#(NBODIES, bodies())
main# = Timer - t
End Function
hello @Jack. interesting code. this is where we see the potential of qb64 compiled with O3 optimization. thanks for sharing.
on my computer :
16.7x seconds : program compiled with qb64 -O3
66.8x seconds : program compiled with original qb64
|