A use for Goto?

Blitz3D Forums/Blitz3D Programming/A use for Goto?

Yasha(Posted 2009) [#1]
Take a look at this:


start=MilliSecs()

For x=1 To 100000000
	;Stuff
Next

Print MilliSecs()-start


start=MilliSecs()

x=1
.loopstart
	;Stuff
x=x+1
If x<100000000 Then Goto loopstart

Print MilliSecs()-start


WaitKey
End


That strikes me as weird. I had previously assumed that For/Next compiled to the same thing as the Goto loop anyway (I don't know why I had the idea to test it, actually). Anyone have any idea why this might be? ("This" meaning I get 390 and 220 for the For/Next and Goto loops respectively, in case anyone out there isn't seeing a difference. Debug is off, obviously.)

OK, there aren't many situations where this kind of optimisation-grinding would be useful... but it's interesting to note.


Nate the Great(Posted 2009) [#2]
wow thats interesting... who woulda thought. in most languages goto is slower than for next loops

edit: tested it, I get numbers all over the place... try running it a few times in a row and see the differences... on a different note, both loops get faster the more I run it... weird


_Skully(Posted 2009) [#3]
Its not really that surprising... for loops have a lot more options than a goto has which requires logic... a goto in ASM is a single op code and a simple increment would be fewer OPS overall.

Something to think about when trying to create really fast algo's eh


Chroma(Posted 2009) [#4]
I get 390 and 379 here.


_Skully(Posted 2009) [#5]
Blitz3D

401
386

Interestingly enough...

In BlitzMax..

Local x:Int

start=MilliSecs()
For x=1 To 100000000
	' stuff
Next
Print MilliSecs()-start

start=MilliSecs()
x=1
#loopstart
	'Stuff
x:+1
If x<100000000 Then Goto loopstart
Print MilliSecs()-start

End


I get...
102
103

{edit} I increased this by a factor of 1000...
1244
1245

they run at the same speed. Nice optimization Mark!


Matty(Posted 2009) [#6]
1 millisecond difference between the two methods using blitzplus on my machine at work.


_Skully(Posted 2009) [#7]
BlitzPlus I get

367
397


Yasha(Posted 2009) [#8]
Interesting. In BlitzMax I have 79 and 101, or 792 and 1002 when multiplying up again - so the Goto loop is actually slower. Both Blitz3D and BlitzMax stay consistent in the proportion of time taken. Maybe this is also partly down to the individual machine?


Ross C(Posted 2009) [#9]
I would imagine these simple intructions maybe be cached on the CPU?


Floyd(Posted 2009) [#10]
I think it's a memory alignment issue. Try padding with some extra commands:
; a = 0
; b = 0
; c = 0


start=MilliSecs()

For x=1 To 100000000
	;Stuff
Next

Print MilliSecs()-start


start=MilliSecs()

x=1
.loopstart
	;Stuff
x=x+1
If x<100000000 Then Goto loopstart

Print MilliSecs()-start


WaitKey
End

Try this four times. Run it, then uncomment the first line and run again. Uncomment the second line etc.


Rroff(Posted 2009) [#11]
Both methods clock in at 180ms +/- 1-2ms here.

Could be a CPU specific opptomisation on certain platforms maybe.


PowerPC603(Posted 2009) [#12]
I tried this code also and got very different results:

3799
11410

So on my laptop (HP Pavilion dv9000), goto is MUCH slower than the for-next loop.

I even tried adding a delay of 2 secs before the start of each loop to make sure the window was drawn, but results stayed the same.


EDIT:
Sorry, those values were with debug enabled.
The new values are:
356
360


Nate the Great(Posted 2009) [#13]
3799
11410



lol I was about to say... now what are your specs? 3.2 ghz 2gb ram? how on earth is that possible... then i saw your edit :)


jfk EO-11110(Posted 2009) [#14]
Don't miss what Floyd said. Some time ago some people have found out that (one some machines, probably AMD only) there is a significat speed diffrence depending on if the jump target, be it the internal FOR/NEXT jump label, or the one used with GOTO lies on an even or an odd address. Eventually it even used to depend on the lowest 2 Bits of the address, so it would have to be an address that can be divided trough 4.

Just try it, add some commands just before the loop starts. It maybe makes a diffrence. (Mark, never mind, I love it anyway)

And btw FOR Loops have some more features, eg: "x=0:For i=1 to x" will be skipped where in a Goto Situation the program may run into an endlessloop and therefor freeze.

Nevertheles I sometimes use Goto. Eg. for Block remarks, or something similar. It just shouldn't be a main component of the program structure, because it spaghettizes your code quickly.


_Skully(Posted 2009) [#15]
spaghettizes


So true and LOL... like Alphagetti


jfk EO-11110(Posted 2009) [#16]
BTW here is the test code for the odd label artefact:
Graphics 640,480,16,1
Delay 5000



count1 = MilliSecs()
For x=1 To 100000000
Next
count2 = MilliSecs()



count3 = MilliSecs()
For x=1 To 100000000
Next
count4 = MilliSecs()

Print count2 - count1
Print count4 - count3
MouseWait
End



Bobysait(Posted 2009) [#17]
with debugmode active, the goto method, is 4 times slower than for/next
without, goto is just a bit slower...

I think the difference is very minor, and just make debugmode being very inefficient...


Kryzon(Posted 2009) [#18]
lol goto was the slower one for me here.

EDIT: aah, it's probably the debug, let me try.


_PJ_(Posted 2009) [#19]
Debugmode does seem to affect speed a lot, but in some circumstances a lot more than others.


Wings(Posted 2009) [#20]
Goto is usable.
but one must have completly controll over all that is bewen.

in goto loop never use these commands

While
Sellect
Loop

Probalby more command not to use...

Goto is ok to use if you only use goto. and dont mix with other controll code commands.