Seite 2 von 9

Re: Goto sinnvoll nutzen

Verfasst: 08.04.2014 20:44
von mk-soft
Äh... mehr Kaftwerke.

Solltest vieleicht mal auch den Zeitpunkt "start" neu setzen...

Code: Alles auswählen

maxx=90000
i=0
start=ElapsedMilliseconds()
top:
i+1
If i<maxx
  a.s="do_something_"+Str(i)
  Goto top
EndIf
out.s+"Goto:"+Str(ElapsedMilliseconds()-start)+" "
start=ElapsedMilliseconds()
For i=1 To maxx-1
  a.s="do_something_"+Str(i)
Next i
out.s+"For Next:"+Str(ElapsedMilliseconds()-start)+" "
start=ElapsedMilliseconds()
i=1
While i <maxx
  a.s="do_something_"+Str(i)
  i+1
Wend
out.s+"While Wend:"+Str(ElapsedMilliseconds()-start)+" "
start=ElapsedMilliseconds()
i=1
Repeat
  a.s="do_something_"+Str(i)
  i+1
Until i=maxx
out.s+"Repeat Until:"+Str(ElapsedMilliseconds()-start)+" "
Debug out
:mrgreen:

Re: Goto sinnvoll nutzen

Verfasst: 08.04.2014 21:19
von NicTheQuick
Ernsthaft, Leute? Jetzt versucht ihr Geschwindigkeitsvergleiche mit Debugger zu machen? Und dann setzt ihr noch den String zusammen während ihr die Zeit stoppt? :roll:

Macht es doch wenn schon richtig, wenn ihr hier wieder komische Tests machen wollt:

Code: Alles auswählen

EnableExplicit

Define.i maxx, i, time
Define.s a = "", out = ""
maxx = 40000000

Macro DoSomething()
	a = "do_something_" + Str(i)
EndMacro

;========= Goto Version 1 =========
time = ElapsedMilliseconds()
i = 0
top1:
If i < maxx
	DoSomething()
	i + 1
	Goto top1
EndIf
time = ElapsedMilliseconds() - time
out + "Goto Version 1: " + time + #LF$

;========= Goto Version 2 =========
time = ElapsedMilliseconds()
i = 0
top2:
If i = maxx
	Goto ende2
EndIf
DoSomething()
i + 1
Goto top2
ende2:

time = ElapsedMilliseconds() - time
out + "Goto Version 2: " + time + #LF$

;========= For-Schleife =========
a = ""
time = ElapsedMilliseconds()
For i = 0 To maxx - 1
	DoSomething()
Next
time = ElapsedMilliseconds() - time
out + "For Next: " + time + #LF$

;========= While-Schleife =========
a = ""
time = ElapsedMilliseconds()
i = 0
While i < maxx
	DoSomething()
	i + 1
Wend
time = ElapsedMilliseconds() - time
out + "While Wend: " + time + #LF$

;========= Repeat-Schleife =========
a = ""
time = ElapsedMilliseconds()
i = 0
Repeat
	DoSomething()
	i + 1
Until i = maxx
time = ElapsedMilliseconds() - time
out + "Repeat Until: " + time + #LF$

MessageRequester("Zeiten", out)
Bei mir ist eigentlich alles gleich schnell. "Goto Version 2" und "For Next" sind aber meistens eher vorne dabei.
Beispielausgabe hat geschrieben:Goto Version 1: 2222
Goto Version 2: 2204
For Next: 2206
While Wend: 2208
Repeat Until: 2189

Re: Goto sinnvoll nutzen

Verfasst: 08.04.2014 22:33
von _sivizius
im Gegenteil, GOTO dauert am längsten. Aber wenn es euch um ein paar µs geht, warum nicht gleich alles in Assembler?

Re: Goto sinnvoll nutzen

Verfasst: 08.04.2014 23:54
von NicTheQuick
Da wir jetzt mittlerweile in diesem Thread immer mehr verrückte Tests machen, dann lasst uns doch gleich mal den von PB generierten ASM-Code begutachten:

Code: Alles auswählen

;========= Goto Version 1 =========
; i = 0
  MOV    qword [v_i],0
; top1:
l_top1:
; If i < maxx
  MOV    r15,qword [v_i]
  CMP    r15,qword [v_maxx]
  JGE   _EndIf2
; DoSomething()
; i + 1
  MOV    r15,qword [v_i]
  INC    r15
  MOV    qword [v_i],r15
; Goto top1
  JMP    l_top1
; EndIf
_EndIf2:


;========= Goto Version 2 =========
; i = 0
  MOV    qword [v_i],0
; top2:
l_top2:
; If i = maxx
  MOV    r15,qword [v_i]
  CMP    r15,qword [v_maxx]
  JNE   _EndIf4
; Goto ende2
  JMP    l_ende2
; EndIf
_EndIf4:
; DoSomething()
; i + 1
  MOV    r15,qword [v_i]
  INC    r15
  MOV    qword [v_i],r15
; Goto top2
  JMP    l_top2
; ende2:
l_ende2:


;========= For-Schleife =========
; For i = 0 To maxx - 1
  MOV    qword [v_i],0
_For5:
  MOV    r15,qword [v_maxx]
  DEC    r15
  CMP    r15,qword [v_i]
  JL    _Next6
; DoSomething()
; Next
_NextContinue6:
  INC    qword [v_i]
  JNO   _For5
_Next6:


;========= While-Schleife =========
; i = 0
  MOV    qword [v_i],0
; While i < maxx
_While7:
  MOV    r15,qword [v_i]
  CMP    r15,qword [v_maxx]
  JGE   _Wend7
; DoSomething()
; i + 1
  MOV    r15,qword [v_i]
  INC    r15
  MOV    qword [v_i],r15
; Wend
  JMP   _While7
_Wend7:


;========= Repeat-Schleife =========
; i = 0
  MOV    qword [v_i],0
; Repeat
_Repeat8:
; DoSomething()
; i + 1
  MOV    r15,qword [v_i]
  INC    r15
  MOV    qword [v_i],r15
; Until i = maxx
  MOV    r15,qword [v_i]
  CMP    r15,qword [v_maxx]
  JNE   _Repeat8
_Until8:
Man sieht jetzt, dass im Grunde jede Schleife das selbe macht, außer die For-Next-Schleife.
Bei alle Schleifen wird 'i' so inkrementiert:

Code: Alles auswählen

  MOV    r15,qword [v_i]
  INC    r15
  MOV    qword [v_i],r15
Außer bei der For-Schleife. Da wird nur das hier gemacht:

Code: Alles auswählen

  INC    qword [v_i]
Das könnte der Unterschied sein, den ich deutlich in den Zeiten sehen kann, wenn ich das Macro 'DoSomething()' komplett leere:
maxx = 400000000 hat geschrieben:Goto Version 1: 1136
Goto Version 2: 1082
For Next: 879
While Wend: 1088
Repeat Until: 1143

Re: Goto sinnvoll nutzen

Verfasst: 09.04.2014 12:42
von bobobo
mk-soft hat geschrieben:
Solltest vieleicht mal auch den Zeitpunkt "start" neu setzen...
Hätte eher mal "GOTO bed oder Kneipe" machen sollen :bounce:

Re: Goto sinnvoll nutzen

Verfasst: 09.04.2014 16:15
von _sivizius
und noch etwas Schwachsinn mehr:

Code: Alles auswählen

EnableExplicit

Define.i maxx, i, time
Define.s a = "", out = ""
maxx = 40000000

Macro DoSomething()
   a = "do_something_" + Str(i)
EndMacro

;========= Goto Version 1 =========
time = ElapsedMilliseconds()
i = 0
top1:
If i < maxx
   DoSomething()
   i + 1
   Goto top1
EndIf
time = ElapsedMilliseconds() - time
out + "Goto Version 1: " + time + #LF$

;========= Goto Version 2 =========
time = ElapsedMilliseconds()
i = 0
top2:
If i = maxx
   Goto ende2
EndIf
DoSomething()
i + 1
Goto top2
ende2:

time = ElapsedMilliseconds() - time
out + "Goto Version 2: " + time + #LF$

;========= For-Schleife =========
a = ""
time = ElapsedMilliseconds()
For i = 0 To maxx - 1
   DoSomething()
Next
time = ElapsedMilliseconds() - time
out + "For Next: " + time + #LF$

;========= While-Schleife =========
a = ""
time = ElapsedMilliseconds()
i = 0
While i < maxx
   DoSomething()
   i + 1
Wend
time = ElapsedMilliseconds() - time
out + "While Wend: " + time + #LF$

;========= Repeat-Schleife =========
a = ""
time = ElapsedMilliseconds()
i = 0
Repeat
   DoSomething()
   i + 1
Until i = maxx
time = ElapsedMilliseconds() - time
out + "Repeat Until: " + time + #LF$
;========= Assembler-Schleife =========
a = ""
time = ElapsedMilliseconds()
EnableASM
  mov   r15, 0
  mov   r14, qword [v_maxx]
  jump:
  inc   r15
  DoSomething()
  dec   r14
  jnz   l_jump
  mov   qword [v_i],r15
DisableASM
time = ElapsedMilliseconds() - time
out + "Assembler: " + time + #LF$

MessageRequester("Zeiten", out)
aber es ist sogar langsamer o.O.

Re: Goto sinnvoll nutzen

Verfasst: 09.04.2014 19:48
von bobobo
Denk Dir doch mal ein Beispiel aus in dem GOTO schneller ist.
So Simple-Schleifen haben wir nun genug.

Re: Goto sinnvoll nutzen

Verfasst: 09.04.2014 20:56
von _sivizius
genug Schleifen? Man kann nie zu viele Schleifen haben *duck*

Re: Goto sinnvoll nutzen

Verfasst: 09.04.2014 23:21
von funkheld
....mov r15, 0.....

Fehlermeldung vom Compiler.

Re: Goto sinnvoll nutzen

Verfasst: 10.04.2014 00:34
von NicTheQuick
funkheld hat geschrieben:....mov r15, 0.....

Fehlermeldung vom Compiler.
Das kommt davon, wenn man kein 64-Bit-System hat. Bei x86 heißen die Register eben anders. :wink: