Hallo,
ich wollte mal testen wie schnell GLBasic eine For-Next-Schleife
abarbeitet. Das Ganze habe ich mit GETTIMERALL() gemessen.
Folgendes Programm zeigt die Zeit an während die Schleife durchlaufen
wird, bis sie abgearbeitet ist. Allerdings stecken in der Schleife ja auch
noch der Print und der Showscreen Befehl.
///////////////////////
FOR i=0 TO 100
zeit=GETTIMERALL()
PRINT zeit/1000,320,240
SHOWSCREEN
NEXT
marke:
PRINT zeit/1000,320,240
SHOWSCREEN
GOTO marke
///////////////////////
Jetzt wollte ich aber wissen, wie lange GLBAsic für die Schleife ohne
Print und Showscreen Befehle braucht.
Jetzt zeigt die Zeit aber 0 an.
Es sieht so aus, als ob die Zeit nur dann angezeigt wird, wenn ein Showscreen
auf Gettimerall() folgt. Kann mir jemand helfen?
///////////////////////// Bei diesem Programm zum Beispiel,
FOR i=0 TO 100000000 braucht GLBasic eindeutig einige
zeit=GETTIMERALL() Zeit, aber zeit=0 ???
//PRINT zeit/1000,320,240
//SHOWSCREEN
NEXT
marke:
PRINT zeit/1000,320,240
SHOWSCREEN
GOTO marke
/////////////////////////
Danke,
Baggi
Versuchs mal so,
zeit1 = GETTIMERALL()
FOR i=0 TO 100
SHOWSCREEN()
NEXT i
zeit2 = GETTIMERALL()
PRINT (zeit2-zeit1)/1000,320,240
KEYWAIT()
Hallo Slayer,
danke für deine Antwort. Irgendwie läuft dein Code
aber nicht bei mir.
Mit ein paar kleinen Änderungen wird der Code compiliert.
Showscreen hat keine (), Next hat kein i und bei Keywait
müssen auch die () weg.
dein Code :
////////////////////////////////
zeit1 = GETTIMERALL()
FOR i=0 TO 100
SHOWSCREEN()
NEXT i
zeit2 = GETTIMERALL()
PRINT (zeit2-zeit1)/1000,320,240
KEYWAIT()
////////////////////////////////
der geänderte Code :
////////////////////////////////
zeit1 = GETTIMERALL()
FOR i=0 TO 100
SHOWSCREEN
NEXT
zeit2 = GETTIMERALL()
PRINT (zeit2-zeit1)/1000,320,240
KEYWAIT
////////////////////////////////
Wenn man dieses Programm jetzt startet, bekommt man lediglich
einen schwarzen Bildschirm. Also nehme ich noch ein paar Änderungen vor.
(Ach so, da fehlt nur ein Showscreen hinter Print.) Dann ist alles OK.
Code:
////////////////////////////////
zeit1 = GETTIMERALL()
FOR i=0 TO 100
SHOWSCREEN
NEXT
zeit2 = GETTIMERALL()
marke:
PRINT (zeit2-zeit1)/1000,320,240
PRINT (zeit2)/1000,320,340
PRINT (zeit1)/1000,320,440
SHOWSCREEN
GOTO marke
////////////////////////////////
Also ich gehe den Code mal durch :
Der Variablen zeit1 wird Gettimerall() übergeben, also
die Zeit die verstrichen ist, seit das Programm läuft, aber ohne
einem vorausgehenden Showscreen Befehl ist zeit1=0 !!!
Dann wird die Schleife durchlaufen. Danach wird der
Variablen zeit2 die verstrichene Programmzeit übergeben.
Das Ganze überprüfe ich jetzt und
zeige (zeit2-zeit1) sowie zeit2 und zeit1 auf dem Bildschirm an.
Nun ist es so, dass zeit1 Null ist.
Deswegen ist (zeit2-zeit1)=zeit2.
Tja aber nichts desto trotz hat mir dein Code geholfen, denn er löst
das Problem. zeit2 ist schon genau die Zeit die ich haben möchte.
Ich habe deinen Code noch ein wenig umgeschrieben.
////////////////////////
FOR i=0 TO 10000000
NEXT
SHOWSCREEN
zeit2 = GETTIMERALL()
marke:
PRINT zeit2/1000,320,240
SHOWSCREEN
GOTO marke
////////////////////////
Zuerst wird die Schleife durchlaufen, dann kommt ein
Showscreen, damit Gettimerall() funktioniert. Die Zeit seid
Beginn des Programms wird an zeit2 übergeben und es geht in die
marke: Goto marke Schleife und zeit2 wird angezeigt.
Das ist dann genau die Zeit, die für die For Next Schleife benötigt
wird + ein Showscreen Befehl.
Damit bin ich schon mal ziemlich zufrieden. Wenn Gettimerall() jetzt
noch ohne einem Showscreen Befehl funktionieren würde, wäre es perfekt.
So, bin fertig. Tut mir leid, dass ich hier jetzt soviel
geschwafelt habe, aber ich musste das klären.
Baggi
Oops:
Sorry, war auf einem anderen Rechner und habe deswegen den Code
nicht überprüft.
Hab da wohl einen etwas anderen Basic-Dialekt rein gebracht ;)
Naja, kann mal passieren.
Aber Du hast es in dem fall ja eh geändert :)
Hallo,
der Wert für GETTIMERALL() wird nur bei SHOWSCREEN aktualisiert. Soll ich das ändern? So geht's jedenfalls:
LIMITFPS -1
SHOWSCREEN
start = GETTIMERALL()
FOR j=0 TO 1000
FOR i=0 TO 10000
NEXT
NEXT
SHOWSCREEN
PRINT (GETTIMERALL() - start), 100, 100
SHOWSCREEN
MOUSEWAIT
Hi Gernot,
so wie ich das verstehe, misst start die Zeit für ein
Showscreen. Da nach der Schleife aber noch ein Showscreen
kommt, müsste man zweimal start von Gettimerall() abziehen, um
nur die Zeit für die Schleife zu haben.
Also so :
////////////////////////////////////////
LIMITFPS -1
SHOWSCREEN
start = GETTIMERALL()
FOR j=0 TO 1000
FOR i=0 TO 10000
NEXT
NEXT
SHOWSCREEN
PRINT (GETTIMERALL() - start*2), 100, 100
SHOWSCREEN
MOUSEWAIT
///////////////////////////////////////
So müsste es doch richtig sein oder ?
Im Grunde ist es nicht so wichtig, ob Gettimerall() nur
bei einem Showscreen aktualisiert wird. Wenn du es trotzdem
ändern könntest, fände ich es besser, dann ist Gettimerall()
unabhängig von Showscreen.
Aber da fällt mir noch was ein zu Timern.
In QBasic gibt es einen Timer bei dem man zwischendurch
die Variable, der man die Zeit zugewiesen hat ändern kann.
Das fände ich auch ziemlich gut, wenn
es das für GLBasic gäbe. Dann könnte man sowas machen :
////////////////
start:
zeit=TIMER
if zeit>=0.25
irgendwas machen
zeit=0
endif
goto start
////////////////
Ach so, wie macht ihr das eigentlich, dass euer Code in so einem
schönen punktierten Fenster erscheint ???
Baggi
QuoteAch so, wie macht ihr das eigentlich, dass euer Code in so einem
schönen punktierten Fenster erscheint ??
Mit BBcode, benutze anstatt die () Klammern [] Klammern
(code) ; am anfang
codezeilen einfügen.........
(/code); am ende
ist im grunde genauso wie wenn Du eine URL angibst,
(url)http://www.glbasic.com(/url)
http://www.glbasic.com
nochwas:
GETTIMERALL() gibt die Zeit an, die das Programm jetzt schon gelaufen ist (also kompletti). Mit GETTIMER() bekommt man die Zeit, die seit dem letzten SHOWSCREEN vergangen ist. Oder genauer: Die Zeit, die das Programm zwischen den letzten beiden SHOWSCREEN gebraucht hat. Das ist vielleicht etwas falsch... Ich werde es in einem Update genauer machen.
Kannst du denn so einen Timer einbauen,
wie ich vorgeschlagen habe ?
start:
zeit=TIMER
if zeit>=0.25
irgendwas machen
zeit=0
endif
goto start
start:
zeit=Timer()
IF zeit>=0.25
irgendwas machen
SetTimer(0)
ENDIF
SHOWSCREEN
GOTO start
FUNCTION SetTimer: n
GLOBAL myTimer = n
ENDFUNCTION
FUNCTION Timer:
LOCAL delta
delta = GETTIMER()
GLOBAL myTime = GLOBAL myTime + delta
RETURN GLOBAL myTime
ENDFUNCTION
Hmm, gibts eigendlich einen Befehl/Funktion wo die zeit ausgibt
seit wann/wie lange das system läuft, in Millisecunden ?
Falls ja, wie heist er ?
Dann hab ich ihn irgendwo übersehen.
GetTickCount unter GLBasic? Gibt's nicht - wozu? Was vielleicht wichtig wäre, echtes Datum+Uhrzeit... Bin ich aber auch schon 'dran.
Quote from: GernotFrischGetTickCount unter GLBasic? Gibt's nicht - wozu? Was vielleicht wichtig wäre, echtes Datum+Uhrzeit... Bin ich aber auch schon 'dran.
Naja, habe mir bis jetzt immer einen eigenen Timer Programmiert für Frameausgabe, geschwindigkeitsmessungen, Animationen........
Alles klar verstehe.
Habe mal ein x=x+1 eingefügt.
Diese wird jetzt also alle paar Sekunden
erhöht.
start:
zeit=Timer()
IF zeit>=6000
x=x+1
SetTimer(0)
ENDIF
PRINT x,100,100
SHOWSCREEN
GOTO start
FUNCTION SetTimer: n
GLOBAL myTime = n //hier war ein r reingerutscht, habe ich entfernt
ENDFUNCTION
FUNCTION Timer:
LOCAL delta
delta = GETTIMER()
GLOBAL myTime = GLOBAL myTime + delta
RETURN GLOBAL myTime
ENDFUNCTION
Allerdings hat diese Methode einen Nachteil :
Die ganze Geschichte ist von der Rechnergeschwindigkeit
abhängig. Also wie schnell die start GOTO start Schleife
durchlaufen wird.
Was mich an diesem Timerkram interessiert, ist ein Programm
zu schreiben, welches auf jedem Rechner in etwa gleich
schnell läuft. Dafür muss der Timer aber auf die Rechnerzeit
zurückgreifen. So wie Gettimerall(). Vielleicht geht ja
sowas was du mit gettimer() gemacht hast auch mit gettimerall() ?
Hmmmmm nicht so einfach.
Ach soooooo!! Alles kloar!
Das hier läuft immer gleich schnell:
x = 0
LIMITFPS -1 // Brüll
WHILE TRUE
PRINT "X", x, 0
x = x + GETTIMER() / 100 // Bisserl langsamer
WEND
Nochmal kurz: GETTIMER() liefert wie lange der letzte Programmdurchlauf + SHOWSCREEN gedauert hat. Der Wert ist irgendwo zwischen 1 und 30 millisecs. Also, immer anstatt x=x+1 je SHOWSCREEN x=x+GETTIMER() * faktor machen.
Alles klar.
Jetzt kann ich x auch auf Null setzten und sowas machen :
x = 0
LIMITFPS -1 // Brüll
WHILE TRUE
PRINT "X", x, 0
x = x + GETTIMER() / 100 // Bisserl langsamer
IF x>=15
y=y+1
x=0
ENDIF
PRINT y,100,100
SHOWSCREEN
WEND
Also nochmal, nur damit ichs kapiert habe :
**********************************************************
Rechnergeschwindigkeit | Bei jedem Durchlauf | nach 60ms |
für den Code zwischen | | |
SHOWSCREEN | | |
| | |
15ms | x=x+15 | x=60 |
| | |
30ms | x=x+30 | x=60 |
**********************************************************
Angenommen da sind zwei Rechner, der eine schafft den Code
zwischen SHOWSCREEN in 15ms, der andere in 30ms. Dann wird
beim langsameren, x alle 30 ms um 30 erhöht. Macht nach 60 ms
genau x=60 und braucht (weil langsam) 2 Durchläufe.
Beim Schnellen wird alle 15 ms um 15 erhöht. Macht nach 60 ms
genau x=60 und schafft (weil schnell) 4 Durchläufe.
Das ist genial.
Sehr schön veranschaulicht.