Raskaat CoolBasic ohjelmat joutuvat usein puristamaan koodista viimeisetkin mehut jotta saavuttavat hyväksyttävän suoritusnopeuden. Siksipä ajattelin että olisi hyvä jakaa enemmänkin tietoa siitä mikä erityisesti CoolBasicilla on tehokasta ja mikä ei.
SCREEN 800,600
//kuinka monta testiä tehdään
Const kertaus = 10
//kuinka monta millisekuntia odotetaan testien välissä
Const odotus = 100
//kuinka monta testattavaa on
Const testattavia = 3
Dim tulos(kertaus,testattavia) As integer
Dim nimi(testattavia) As String
//tähän nimi testikoodille
nimi(1) = "lukittu line"
nimi(2) = "line"
nimi(3) = "box"
Global viivoja As integer
Testaa()
//tänne nimeä vastaavaan caseen testikoodi
Function Laskenta(i)
Select i
Case 1
Lock
For o=1 To viivoja
Line 0,0,100,0
Next o
Unlock
Case 2
For o=1 To viivoja
Line 0,0,100,0
Next o
Case 3
For o=1 To viivoja
Box 0,0,100,1,1
Next o
End Select
End Function
//tänne testeihin liittyviä muutoksia, jotta testicaset ei
//ole joka kierros samoja.
Function Kierrosmuutos(kierros)
viivoja=kierros*20000
Print ""
Print "Piirretään "+viivoja+" viivaa."
End Function
//tämä suorittaa itse testit
Function Testaa()
For o=1 To kertaus
Kierrosmuutos(o)
For u=1 To testattavia
Wait odotus
tulos(o,u)=Timer()
Laskenta(u)
tulos(o,u)=Timer()-tulos(o,u)
Print nimi(u)+" "+tulos(o,u)+" ms"
tulos(0,u)=tulos(0,u)+tulos(o,u)
Next u
Next o
Print ""
Print "--- Keskiarvot ---"
For u=1 To testattavia
Print nimi(u)+" "+Float(tulos(0,u))/Float(kertaus)+" ms"
Next u
WaitKey
End Function
Ruudun lukitseminen Lock komennolla ennen viivojen piirtämistä vauhdittaa piirtoa hurjasti. Box komentokin tuntuu olevan hieman lukitsematonta viivaa nopeampi kunhan määrä pysyy kohtuullisena (<140000).
SCREEN 800,600
//kuinka monta testiä tehdään
Const kertaus = 10
//kuinka monta millisekuntia odotetaan testien välissä
Const odotus = 100
//kuinka monta testattavaa on
Const testattavia = 3
Dim tulos(kertaus,testattavia) As integer
Dim nimi(testattavia) As String
//tähän nimi testikoodille
nimi(1) = "distance"
nimi(2) = "sqrt+pow"
nimi(3) = "sqrt+mult"
Global fTestNumber1 As Float, fTestNumber2 As Float, iTestAmount As integer
Testaa()
//tänne nimeä vastaavaan caseen testikoodi
Function Laskenta(i)
Select i
Case 1
For o=1 To iTestAmount
a=Distance(0,0,fTestNumber1,fTestNumber2)
Next o
Case 2
For o=1 To iTestAmount
a=Sqrt(fTestNumber1^2+fTestNumber2^2)
Next o
Case 3
For o=1 To iTestAmount
a=Sqrt(fTestNumber1*fTestNumber1+fTestNumber2*fTestNumber2)
Next o
End Select
End Function
//tänne testeihin liittyviä muutoksia, jotta testicaset ei
//ole joka kierros samoja.
Function Kierrosmuutos(kierros)
iTestAmount= kierros*200000
fTestNumber1=Rnd(-100.0,1000.0)
fTestNumber2=Rnd(-100.0,1000.0)
Print ""
Print "Lasketaan pisteen ("+fTestNumber1+","+fTestNumber2+") etäisyys origosta "+iTestAmount+" kertaa."
End Function
//tämä suorittaa itse testit
Function Testaa()
For o=1 To kertaus
Kierrosmuutos(o)
For u=1 To testattavia
Wait odotus
tulos(o,u)=Timer()
Laskenta(u)
tulos(o,u)=Timer()-tulos(o,u)
Print nimi(u)+" "+tulos(o,u)+" ms"
tulos(0,u)=tulos(0,u)+tulos(o,u)
Next u
Next o
Print ""
Print "--- Keskiarvot ---"
For u=1 To testattavia
Print nimi(u)+" "+Float(tulos(0,u))/Float(kertaus)+" ms"
Next u
WaitKey
End Function
Distancen käyttö näyttäisi olevan huomattavasti nopeampaa kuin laskea etäisyys neliöjuuren ja kahden potenssin avulla. Kahden potenssin vaihtaminen kertolaskuun tehostaa selvästi muttei aivan yllä distancen tasolle.
SCREEN 800,600
//kuinka monta testiä tehdään
Const kertaus = 20
//kuinka monta millisekuntia odotetaan testien välissä
Const odotus = 100
//kuinka monta testattavaa on
Const testattavia = 3
Dim tulos(kertaus,testattavia) As integer
Dim nimi(testattavia) As String
//tähän nimi testikoodille
nimi(1) = "for"
nimi(2) = "while"
nimi(3) = "repeat"
Global fTestNumber1 As Float, fTestNumber2 As Float, iTestAmount As Integer
Testaa()
//tänne nimeä vastaavaan caseen testikoodi
Function Laskenta(i)
Select i
Case 1
For o=0 To iTestAmount
t = fTestNumber1 * fTestNumber2
Next o
Print "f "+o
Case 2
o = 0
ton = iTestAmount + 1 // optimization!
While o < ton
t = fTestNumber1 * fTestNumber2
o + 1
Wend
Print "w "+o
Case 3
o = 0
Repeat
t = fTestNumber1 * fTestNumber2
o + 1
Until o > iTestAmount
Print "r "+o
End Select
End Function
//tänne testeihin liittyviä muutoksia, jotta testicaset ei
//ole joka kierros samoja.
Function Kierrosmuutos(kierros)
fTestNumber1 = Rnd (-1000, 1000)
fTestNumber2 = Rnd (-1000, 1000)
iTestAmount = kierros * 200000
Print ""
Print "Luupataan... "+fTestNumber1+" x "+fTestNumber2
End Function
//tämä suorittaa itse testit
Function Testaa()
For o=1 To kertaus
Kierrosmuutos(o)
For u=1 To testattavia
Wait odotus
tulos(o,u)=Timer()
Laskenta(u)
tulos(o,u)=Timer()-tulos(o,u)
Print nimi(u)+" "+tulos(o,u)+" ms"
tulos(0,u)=tulos(0,u)+tulos(o,u)
Next u
Next o
Print ""
Print "--- Keskiarvot ---"
For u=1 To testattavia
Print nimi(u)+" "+Float(tulos(0,u))/Float(kertaus)+" ms"
Next u
WaitKey
End Function
Repeat on nopein!1!!!11 En kyllä tiedä teinkö oikein, mutta tuommosta.
— dev.tuhoojabotti.com — “Programmer (noun): An organism that turns caffeine into code.”
timr1 = Timer()
Repeat
a = a + 1
If a > 100000 Then Exit
Forever
timr1 = Timer() - timr1
timr2 = Timer()
While True
b = b + 1
If b > 100000 Then Exit
Wend
timr2 = Timer() - timr2
timr3 = Timer()
For i = 0 To i+1
c = c + 1
If c > 100000 Then Exit
Next i
timr3 = Timer() - timr3
//MaGetzUb's invented
timr4 = Timer()
Loop:
e = e + 1
If e > 100000 Then Goto out
Goto Loop
out:
timr4 = Timer()-timr4
Print "Repeat - Until/Forever took: "+timr1+"ms"
Print "While - Wend took: "+timr2+"ms"
Print "ForTo - Next took: "+timr3+"ms"
Print "Goto loop took: "+timr4+"ms"
WaitKey
EDIT:
Oma keksintöni "goto loop" on kaikista nopein ainakin minun koneellani. Muilla loopeilla ottaa yli 30ms, mutta Goto loop otti 25ms kun testasin.
Solar Eclipse
Meneillä olevat Projektit:
Solar Engine - Modernin OpenGL rajapinnan päällä toimiva 3D ja 2D pelimoottori.
Minulla Repeat/Forever ja Goto toimivat aivan yhtä nopeasti(13ms). Ne olivat noin 13% nopeampia kuin While/Wend ja melkein kaksi kertaa nopeampia kuin For/Next.
Enpä usko että nuo looppien nopeudet kuitenkaan ovat millään tavalla ratkaisevia, joten jos voisitte keskittyä tarkkailemaan jotain oikeasti merkitseviä nopeuseroja?
MIelenkiintoista... Lock+Putpixel2+Unlock tuntuu olevan minulla aina nopeampi kuin Putpixel, vaikka piirrettäisiin vain yksi pikseli. Eli siis vaikka piirtäisit vain yhden pikselin kannattaa käyttää Putpixel2:sta...
Latexi95 wrote:MIelenkiintoista... Lock+Putpixel2+Unlock tuntuu olevan minulla aina nopeampi kuin Putpixel, vaikka piirrettäisiin vain yksi pikseli. Eli siis vaikka piirtäisit vain yhden pikselin kannattaa käyttää Putpixel2:sta...
esa94 wrote:
Riippuu kuinka kauan lukitseminen kestää
Ai niin... Totta. Tein testini vakio ruudunkoolla suoraan ruudulle. Silloin lukitseminen oli melkein kaksi kertaa nopeampi tapa(lukittu noin 420ms ja lukitsematon 750ms).