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.
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 1:11 am
by MaGetzUb
Distance on n. 57% nopeampi kutsuttaessa sitä 10K kertaa peräkkäin, kuin laskukaava.
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.
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 7:07 pm
by MaGetzUb
En tiedä sitten.. mutta tämä on varmaan parempi testaustyyli:
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.
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 8:01 pm
by Kille
Minun koneella nopein oli repeat(12ms), whileWend ja Goto 14ms ja ForTo 23 ms.
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 8:24 pm
by MaGetzUb
Kille wrote:Minun koneella nopein oli repeat(12ms), whileWend ja Goto 14ms ja ForTo 23 ms.
Näyttäisi olevan aika pitkälti konekohtaista..
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 9:49 pm
by Latexi95
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.
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 9:54 pm
by valscion
Enpä usko että nuo looppien nopeudet kuitenkaan ovat millään tavalla ratkaisevia, joten jos voisitte keskittyä tarkkailemaan jotain oikeasti merkitseviä nopeuseroja?
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 10:34 pm
by Latexi95
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...
Re: Suoritusnopeuden vertailua
Posted: Sun Jul 03, 2011 11:09 pm
by esa94
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...
Riippuu kuinka kauan lukitseminen kestää
Re: Suoritusnopeuden vertailua
Posted: Mon Jul 04, 2011 12:40 am
by Latexi95
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).