Different type of loop
Blitz3D Forums/Blitz3D Programming/Different type of loop
| ||
I understand you can useWhile Wend Repeat Forever Repeat Until For Next But... would it be any worse/better if we used........... Graphics 800,600,0,2 SetBuffer BackBuffer() AppTitle "Function loop ;)" omg_loop() Function omg_loop() If KeyHit(1) End Cls For k = 2 To 255 If KeyDown(k) Color 255,255,255 Rect 0,0,GraphicsWidth(),GraphicsHeight() Color 0,0,0 Text GraphicsWidth()/2,GraphicsHeight()/2,":D OM NOm NomNNMOm TEH LEWP!!!11!!",1,1 EndIf Next Flip omg_loop() End Function .....a function for a loop? |
| ||
hi try: Graphics 800,600,0,2 Global Entradas Global Salidas SetBuffer BackBuffer() AppTitle "Function loop ;)" omg_loop() Function omg_loop() Entradas = Entradas + 1 If KeyHit(1) End Cls For k = 2 To 255 If KeyDown(k) Color 255,255,255 Rect 0,0,GraphicsWidth(),GraphicsHeight() Color 0,0,0 Text GraphicsWidth()/2,GraphicsHeight()/2,":D OM NOm NomNNMOm TEH LEWP!!!11!!",1,1 EndIf Next Text 20,20,"Entradas/Salidas: "+Entradas+" / "+Salidas Flip omg_loop() Salidas = Salidas + 1 End Function as you can see, you are entering but never exiting the function, that should end with a stack overflow. If you call a function recursivelly you have to had a way out. Juan |
| ||
Um, the way I have works just fine, I'm just wondering if it's any better or worse than using the proper loops. Edit: Oh I see what you mean..... it's calling the function a million times... and... ohhhhhh stack.. stacking overflow... I get it ;) So therefore this way is BBAAADDDDDD! Edit2: OH, that's why you have that last variable, I see that both the variables would be the same if this were a proper loop but once the function is called again, it skips that last variable. ...no idea what Entradas and Salidas mean, or even what language that's in... but I understand what you were trying to show. |
| ||
sorry, Entradas is Ins (or entrances) and Salidas are outs or Exits the idea where not to cofuse you. My intention was that you see that you never return from the funtion, so the variable Salidas (incremented on exit) never get incremented. Hope you get the point best regards Juan (by the way, is spanish) |
| ||
I have done some testing on this, an it seems that although ForNext, Repeat Until are around the same kinda speed, While/Wend is significantly faster |
| ||
wow At first I think that a For/Next in wich the ammount of loops probably were known in advance should be compiled more eficiently than a While/Wend that should end more or less unexpecly! I supose that the conditions you used where simple and the task's inside the loops were the same or considerably the same. Any idea for that behavior, or knowledge about innerworkings. Juan |
| ||
Yes I understand the point :) "While/Wend is significantly faster " :D Yay! I use While/Wend for my main program loop, always, so I'm glad to hear it's faster than the others. When I first started learning about loops in blitz, it kind of scared me that there was more than one way, but I've learned that they pretty much do the same thing. |
| ||
Ive no idea why it's so. It MIGHT be possible that different CPU's (or manufacturers of CPU's could give different results, for the sake of informaiton, I am running an AMD X2 64 5600+ chip My test was done with the following: ClearWorld SetBuffer FrontBuffer() Global FN1#=0 Global FN2#=0 Global FN3#=0 Global WW1#=0 Global WW2#=0 Global WW3#=0 Global RU1#=0 Global RU2#=0 Global RU3#=0 x=0 ClsColor 0,0,0 Cls ClsColor 255,255,255 Global timer% Delay 1000 Cls timer%=MilliSecs() For x=0 To 33554432 Next stoptime=MilliSecs() FN1=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() While x<=33554432 x=x+1 Wend stoptime=MilliSecs() WW1=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() Repeat x=x+1 Until x>33554432 stoptime=MilliSecs() RU1=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() For x=0 To 33554432 Next stoptime=MilliSecs() FN2=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() While x<=33554432 x=x+1 Wend stoptime=MilliSecs() WW2=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() Repeat x=x+1 Until x>33554432 stoptime=MilliSecs() RU2=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() For x=0 To 33554432 Next stoptime=MilliSecs() FN3=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() While x<=33554432 x=x+1 Wend stoptime=MilliSecs() WW3=stoptime-timer ClsColor 0,0,0 Cls ClsColor 255,255,255 x=0 Delay 1000 Cls timer%=MilliSecs() Repeat x=x+1 Until x>33554432 stoptime=MilliSecs() RU3=stoptime-timer ClsColor 0,0,0 Color 255,255,255 Cls Print "Mean For/Next : "+Int((FN1#+FN2#+FN3#)/3.0)+"ms" Print "Mean While/Wend: "+Int((WW1#+WW2#+WW3#)/3.0)+"ms" Print "Mean Repeat/Until: "+Int((RU1#+RU2#+RU3#)/3.0)+"ms" Strangely, though.. I have just run the program again a few times, and NOW it seems to indicate ForNext is quicker :S oops! |
| ||
but I've learned that they pretty much do the same thing They don't. They're hugely different.While... Wend tests the condition at the start of the loop. The loop repeats until the condition is false. Repeat... Until, tests the condition at the end of the loop - code in the loop will always run at least once. Repeat... Forever, will.... repeat a loop forever, obviously. To get out of it you must manually call an Exit. For... Next, executes a loop a specific number of times. Two things about your original code: 1. It *will* fail with a stack overflow eventually. Your function is calling itself repeatedly and it is not possible for the function to exit and remove the pointer from the stack. 2. There is no point in checking that many values with KeyDown. KeyDown uses scancodes, not ASCII codes. Much better to just check the ones you want. [edit] what on God's earth is that code above meant to prove? Your For/Next loop will obviously be quicker as you aren't doing anything in it like you are with the others. |
| ||
I did understand that tiny little difference between the loops, just didn't feel like explaining it heh. But the reason I did that with the For k = 2 to 255 was because I saw someone else use something like it, and I knew that GetKey() wouldn't respond to every key. I had it with just If KeyDown(57) or MouseDown(1) but wanted you all to be able to press any key to test it. |
| ||
Yeah, GetKey() pretty much only works with ASCII keys, that is, keys that have letters, number or symbols. GetKey() is actually extremely handy for text input; try this little snippet:SetBuffer BackBuffer() While Not KeyHit(1) Cls GK = GetKey() If GK <> 0 TextLine$ = TextLine + Chr(GK) EndIf Text 0,0,TextLine + "_" Flip Wend Do some typing & see what happens. Also notice that when using GetKey(), the use of the Shift key is automatically compensated for. Try typing "AaBb." |
| ||
LOL... try THAT little snippet you say? I've already created my own little fancy pancy um... texty thingy... heh.Graphics3D 800,600,0,2 SetBuffer BackBuffer() PositionEntity CreateCamera(),0,0,-5 CreateLight() CreateCube() Locate 0,20 a$=FUNC_OutputMessage(0,8,"Text + render first: ",1) b$=FUNC_OutputMessage(0,8,"Text - render first: ",0) Print a Print b WaitKey End Function FUNC_OutputMessage$(x%,y%,parameter$="",render_first%=1) Local TempLabel$ Local Parameter_Offset% = Len(parameter)*FontWidth() Local S_TextMessage_Message$ Local I_TextMessage_Column% Local I_TextMessage_Time_Delete%,I_TextMessage_Time_Arrow%,I_TextMessage_Time_Blink% FUNC_FlushInput() Repeat Cls If render_first = 1 RenderWorld EndIf ;BackSpace Start If KeyHit(14) Or KeyHit(211) Then FUNC_FlushInput() If S_TextMessage_Message <> "" Then If I_TextMessage_Column > 0 Then TempLabel$ = Right(S_TextMessage_Message,Len(S_TextMessage_Message)-I_TextMessage_Column) S_TextMessage_Message = Left(S_TextMessage_Message, I_TextMessage_Column-1 )+TempLabel I_TextMessage_Column = I_TextMessage_Column - 1 EndIf EndIf EndIf If KeyDown(14) Or KeyDown(211) Then FUNC_FlushInput() I_TextMessage_Time_Blink = 0 I_TextMessage_Time_Blink = I_TextMessage_Time_Blink + 1 If I_TextMessage_Time_Blink > 25 Then I_TextMessage_Time_Blink = 25 If S_TextMessage_Message <> "" Then If I_TextMessage_Column > 0 Then TempLabel$ = Right(S_TextMessage_Message,Len(S_TextMessage_Message)-I_TextMessage_Column) S_TextMessage_Message = Left(S_TextMessage_Message, I_TextMessage_Column-1 )+TempLabel I_TextMessage_Column = I_TextMessage_Column - 1 EndIf EndIf EndIf Else I_TextMessage_Time_Blink = 0 EndIf ;BackSpace End ;Enter Start If KeyHit(28) Then FUNC_FlushInput() DebugLog "S_TextMessage_Message = " + S_TextMessage_Message If Trim(S_TextMessage_Message) <> "" Return S_TextMessage_Message Else Return "" EndIf EndIf ;Enter End ;Arrow Keys Start If KeyHit(203) Then FUNC_FlushInput() I_TextMessage_Column = I_TextMessage_Column - 1 EndIf If KeyHit(205) Then FUNC_FlushInput() I_TextMessage_Column = I_TextMessage_Column + 1 EndIf If KeyDown(203) Then FUNC_FlushInput() I_TextMessage_Time_Blink = 0 I_TextMessage_Time_Arrow = I_TextMessage_Time_Arrow + 1 If I_TextMessage_Time_Arrow > 25 Then I_TextMessage_Time_Arrow = 25 I_TextMessage_Column = I_TextMessage_Column - 1 EndIf ElseIf KeyDown(205) Then FUNC_FlushInput() I_TextMessage_Time_Blink = 0 I_TextMessage_Time_Arrow = I_TextMessage_Time_Arrow + 1 If I_TextMessage_Time_Arrow > 25 Then I_TextMessage_Time_Arrow = 25 I_TextMessage_Column = I_TextMessage_Column + 1 EndIf Else I_TextMessage_Time_Arrow = 0 EndIf ;Arrow Keys End ;Home End Keys Start If KeyHit(199) Then FUNC_FlushInput() I_TextMessage_Time_Blink = 0 I_TextMessage_Column = 0 EndIf If KeyHit(207) Then FUNC_FlushInput() I_TextMessage_Time_Blink = 0 I_TextMessage_Column = Len(S_TextMessage_Message) EndIf ;Home End Keys End ;MouseHit 1 Start If MouseDown(1) Then If MouseY() => y Then If MouseY() <= y+FontHeight() Then I_TextMessage_Time_Blink = 0 I_TextMessage_Column = (MouseX()/Float(FontWidth())) EndIf EndIf EndIf ;MouseHit 1 Start Local TempKey% = GetKey() If TempKey <> 0 DebugLog "TempKey = " + TempKey Select TempKey ;ASCII ;Delete 127 ;Left 31 ;Right 30 ;Up 28 ;Down 29 ;Escape/Esc 27 ;Enter/Return 13 ;Backspace 8 ;Home 1 ;End 2 Case 127, 31,30,29,28, 13,8 ,1,2 FUNC_FlushInput() ;Does nothing if those keys are pressed Case 27 FUNC_FlushInput() Return "" Default FUNC_FlushInput() I_TextMessage_Time_Blink = 0 TempLabel$ = Right(S_TextMessage_Message,Len(S_TextMessage_Message)-I_TextMessage_Column) S_TextMessage_Message=Left(S_TextMessage_Message,I_TextMessage_Column)+Chr(TempKey)+TempLabel I_TextMessage_Column = I_TextMessage_Column + 1 End Select EndIf If I_TextMessage_Column > Len(S_TextMessage_Message) Then I_TextMessage_Column = Len(S_TextMessage_Message) ElseIf I_TextMessage_Column < 0 I_TextMessage_Column = 0 EndIf I_TextMessage_Time_Blink = I_TextMessage_Time_Blink + 1 If I_TextMessage_Time_Blink < 25 Rect Parameter_Offset+x+Float(I_TextMessage_Column*FontWidth())-(FontWidth()*.5)+3,y-(FontWidth()*.5), 3,FontHeight() EndIf If I_TextMessage_Time_Blink > 50 I_TextMessage_Time_Blink = 0 EndIf Text x,y,parameter+S_TextMessage_Message,0,1 Flip Forever End Function Function FUNC_FlushInput() FlushJoy() FlushKeys() FlushMouse() End Function |