"Minimalisten"-Contest

  • Hab mal den Geschwindigkeitsvergleich für diesen Contest gemacht:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstants.au3>
    #Include <GuiListView.au3>
    #include <array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    #region Variablen definieren
    Global $ZeitErgebnisse = ObjCreate("System.Collections.ArrayList")
    If @error Then
    MsgBox(0, "", "Fehler bei der Objekt-Erstellung")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Global $TimerDiffTime
    Global $Name, $Zeitsumme, $Zeitquadratsumme, $ZeitPunkt, $Zeit, $TempArray[3], $N, $X
    Global $GUI, $ListView, $Button, $eins, $e, $RahmenZeit
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    ;------------------------------------------------------------------------------------------
    ;Anzahl der Messdurchläufe angeben - je höher N umso genauer wird die gemessene Zeitangabe:
    Global $N = 3000
    ;------------------------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "Oscar"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Global $z, $t = ' 01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849'
    For $i = 0 To 6
    $r = Random(1, 49 - $i, 1) * 2
    $z &= StringMid($t, $r, 2) & StringLeft(' | ', 2 + ($i = 5) * 4)
    $t = StringMid($t, 1, $r - 1) & StringMid($t, $r + 2)
    Next
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "GTASpider"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Local $a[49], $sR, $sT, $rnd
    For $i = 1 To 49
    $a[$i - 1] = $i
    Next
    Do
    $i += Assign("rnd", Random(0, 48))
    $sR &= $a[$rnd] & ","
    $a[$rnd] = ''
    Until $i > 55
    While $sT = ''
    $sT = $a[Random(0, 48) ]
    WEnd
    $z = StringTrimRight($sR, 1) & "|" & $sT
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "BugFix 1"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Global $a[7] = [0, 0, 0, 0, 0, 0, 0]
    Do
    $X = Random(1, 49, 1)
    For $i = 0 To UBound($a) - 1
    If $a[$i] > 0 And $a[$i] = $X Then ExitLoop
    If $a[$i] = 0 Then
    $a[$i] = $X
    ExitLoop
    EndIf
    Next
    Until $a[UBound($a) - 1] <> 0
    $z = $a[0] & ' ' & $a[1] & ' ' & $a[2] & ' ' & $a[3] & ' ' & $a[4] & ' ' & $a[5] & ' Z: ' & $a[6]
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "Xenobiologist"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Global $z = ' ', $B = ''
    Do
    $B = Random(1, 49, 1)
    If Not StringRegExp($z, '(?<= )' & $B & '(?= )') Then $z &= $B & ' '
    Until StringInStr($z, ' ', 0, 8)
    $z = 'Lottoziehung ' & @TAB & ':' & StringTrimRight($z, 3) & @CRLF & 'Zusatzzahl ' & @TAB & ': ' & StringRight($z, 3) & @CRLF & 'Superzahl' & @TAB & @TAB & ': ' & Random(1, 9, 1) & @CRLF
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "BugFix 2"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Global $str = '', $B = 0, $sum = 0, $a[49] = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, 1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 35184372088832, 70368744177664, 140737488355328, 281474976710656]
    Do
    $r = Random(0, 48, 1)
    If Not BitAND($sum, $a[$r]) Then
    $sum = BitOR($sum, $a[$r])
    If $B < 6 Then $str &= $r + 1 & ' '
    If $B = 6 Then $str &= ' Z: ' & $r + 1
    $B += 1
    EndIf
    Until $B = 7
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Zeitaufwand der Methode bestimmen
    $Name = "PhilRip"
    $Zeitquadratsumme = 0
    $Zeitsumme = 0
    SplashTextOn("Test der Methode:", @CRLF & $Name, 250, 60)

    [/autoit] [autoit][/autoit] [autoit]

    For $XXX = 1 To $N
    $ZeitPunkt = TimerInit()

    ;---------Code-----------
    Dim $lotto[7]
    For $i = 0 To 5
    $ran = Random(1, 49, 1)
    If _ArraySearch($lotto, $ran) = 1 Then
    $i -= 1
    Else
    $lotto[$i] = $ran
    EndIf
    Next
    $lotto[6] = Random(1, 9, 1)
    ;------------------------
    $Zeit = TimerDiff($ZeitPunkt)

    $Zeitsumme += $Zeit
    $Zeitquadratsumme += $Zeit ^ 2
    Next
    $TempArray[0] = $Name
    $TempArray[1] = $Zeitsumme / $N
    $TempArray[2] = Sqrt((($N * $Zeitquadratsumme) - ($Zeitsumme ^ 2)) / ($N * ($N - 1)))
    $ZeitErgebnisse.add ($TempArray)
    SplashOff()
    #endregion

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    #region Auswerten und Vergleichen
    _ArrayListSort2Dim($ZeitErgebnisse, 1, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $eins = $ZeitErgebnisse.Item (0)

    [/autoit] [autoit][/autoit] [autoit]

    $GUI = GUICreate("Ergebnisse", 633, 307, 193, 115)
    $ListView = GUICtrlCreateListView("Name|Zeit [ms]|Verhältnis|Standardabweichung [ms]|rel. Abweichung", 0, 0, 632, 265)
    $Button = GUICtrlCreateButton("O.K.", 240, 272, 121, 33, 0)

    [/autoit] [autoit][/autoit] [autoit]

    _GUICtrlListView_SetColumnWidth ($ListView, 0, 203)
    _GUICtrlListView_SetColumnWidth ($ListView, 1, 100)
    _GUICtrlListView_SetColumnWidth ($ListView, 2, 75)
    _GUICtrlListView_SetColumnWidth ($ListView, 3, 150)
    _GUICtrlListView_SetColumnWidth ($ListView, 4, 100)

    [/autoit] [autoit][/autoit] [autoit]

    For $e In $ZeitErgebnisse
    GUICtrlCreateListViewItem($e[0] & '|' & Round($e[1], 3) & '|' & Round($e[1] / $eins[1], 1) & '|' & Round($e[2], 4) & '|' & Int(100 * $e[2] / $e[1]) & '%', $ListView)
    Next

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    Case $Button
    Exit
    EndSwitch
    WEnd
    #endregion

    [/autoit] [autoit][/autoit] [autoit]

    ;Sortiert eine ArrayList mit enthaltenem Array nach einem Index dieses Arrays im Selection-Sort-Algorithmus
    ;Author: [email='AspirinJunkie@german-nlite.de'][/email]
    Func _ArrayListSort2Dim(ByRef $ArrayList, $DimIndex, $Descending = 0)
    Local $minIndex[2], $SortValue

    [/autoit] [autoit][/autoit] [autoit]

    If Not IsObj($ArrayList) Then Return SetError(1, 1, 0)
    If $ArrayList.count = 0 Then Return SetError(2, 2, 0)

    $SortValue = $ArrayList.Item (0)
    If UBound($SortValue) <= $DimIndex Then Return SetError(3, 3, 0)

    If $ArrayList.count < 2 Then Return SetError(4, 4, 0)

    For $i = 0 To $ArrayList.count - 1
    $SortValue = $ArrayList.Item ($i)
    $SortValue = $SortValue[$DimIndex]

    [/autoit] [autoit][/autoit] [autoit]

    $minIndex[0] = $i
    $minIndex[1] = $SortValue

    [/autoit] [autoit][/autoit] [autoit]

    For $e = $i + 1 To $ArrayList.count - 1
    $SortValue = $ArrayList.Item ($e)
    $SortValue = $SortValue[$DimIndex]

    [/autoit] [autoit][/autoit] [autoit]

    If $SortValue < $minIndex[1] Then
    $minIndex[0] = $e
    $minIndex[1] = $SortValue
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    If Not ($minIndex[0] = $i) Then
    $ArrayList.Insert ($i, $ArrayList.Item ($minIndex[0]))
    $ArrayList.Insert ($minIndex[0] + 1, $ArrayList.Item ($i + 1))
    $ArrayList.RemoveAt ($minIndex[0] + 2)
    $ArrayList.RemoveAt ($i + 1)
    EndIf
    Next
    If $Descending Then $ArrayList.Reverse
    Return 1
    EndFunc

    [/autoit]

    McPoldy´s Skript brachte einen Fehler und progandy´s Skript blieb bei mir hängen weswegen ich die beiden rausgelassen habe.

    • Offizieller Beitrag

    Hi,

    was pee meint ist, wenn du ein 1 Sekunden Skript laufen läßt, dann kann es immer passieren, dass gerade in diesem Moment deine Firewall oder der Virenscanner meint er müsste auch mal was tun. :D

    Deshalb halte ich die Methode X mal laufen lassen und Durchschnitt ermitteln für besser.

    Um eine Aussage bzgl. RAM und CPU zu bekommen müsste mal sicherlich auf was externes schwenken, dafür ist Autoit denke ich nicht geeignet.

    Mega

  • Exakt das ist ja das Grundkonzept meines Skriptes ;)
    Aber auch wenn man nur mehrmals durchlaufen lässt und Durchschnitt bildet hat man keinen blassen Schimmer wie genau die Ergebnisse sind.
    Deswegen berechne ich ja noch extra die Standardabweichung um die Messergebnisse auch qualitativ bewerten zu können.

  • Die Abweichungen sind bei dir deutlich zu krass - die Messdaten sind in dem Fall quasi nutzlos um eine vernünftige Aussage zu treffen.
    Die Reihenfolge ist bei mir aber gleich, nur Oscar und Xeno deren Werte fast identisch sind sind vertauscht.
    Deshalb kann ich mir die Ergebnisse gerade von Xeno´s Skript bei progandy nicht wirklich erklären ( @progandy - hast du die Implementierung so übernommen oder noch was geändert?).
    Zumindestens zeigt es das die Werte natürlich in Abhängigkeit des Systems schwanken.
    Also hier mal meine Ergebnisse dazu mit vernünftigeren Standardabweichungen:

    autoit.de/wcf/attachment/1842/

    P.S.: @mega - mal keine falsche Bescheidenheit - dein Skript ist zumindestens bei mir das performanteste ;)

    • Offizieller Beitrag

    Hi,

    naja das kann Zufall sein. Ich mache ja eine Schleife bis keine Zahlen doppelt sind. Wenn ich Glück habe klappt es. Rein theoretisch könnte es auch ewig dauern, wenn die sechste Zahl (ich mache ja 6 aus 49 + Zusatz und Superzahl) immer eine der 5 vorher gezogenen ist.

    Das Skript würde also bei 48 aus 49 sehr sehr lange brauchen :D
    (dann hätte ich es aber auch anders gemacht :P )

    Mega

    • Offizieller Beitrag

    Genau das ist das Problem bei der Laufzeitmessung dieser Scripts. Der Zufallsfaktor! Wenn in einer Schleife nach der Ziehung geprüft wird, ob die Zahl bereits gezogen wurde, hängt die Laufzeit eben sehr von Random() ab.

    Bei zufallsunabhängigen Scripts bin ich aber durchaus für eine "Mehrfachdurchlauf-Mittelwertbildung-Laufzeitmessung". :)

    • Offizieller Beitrag

    Sorry, dass ich diesen alten Thread nochmal ausgrabe, aber ich habe mich gefragt, ob es noch schneller geht, als mit dem Script von Xeno.

    Rausgekommen ist dabei dieses hier:

    [autoit]


    Global $z = ''
    For $i=0 To 6
    Do
    $r = Random(1,49,1) & ' '
    Until Not StringInStr($z,$r)
    $z &= $r
    If $i=5 Then $z &= ' Zusatzzahl= '
    Next
    MsgBox(0,'',$z)

    [/autoit]

    Und das ist tatsächlich nochmal schneller als Xeno's Script.

    Ergebnis (bei 50.000 Durchläufen):
    Scriptomatic.zip

    P.S.: Bei GtaSpider habe ich...

    [autoit]

    Local $a[49], $sR, $sT, $rnd

    [/autoit]


    in...

    [autoit]

    Local $a[49], $sR='', $sT, $rnd

    [/autoit]


    geändert. Dies führt zu gerechteren Ergebnissen seines Scripts.

    • Offizieller Beitrag

    Hi,

    kannst du dies mal testen?

    [autoit]

    Global $z = ''
    For $i = 0 To 6
    Do
    $r = Random(1, 49, 1) & ' '
    Until Not StringInStr($z, $r)
    $z &= $r
    Next
    MsgBox(0, '', StringTrimRight($z, 4) & ' Zusatzzahl= ' & StringRight($z, 2))

    [/autoit]

    Ich denke nochmal über eine andere Methode nach.

    Hmmh diese :

    [autoit]

    Global $a[50], $z
    For $i = 0 To 6
    Do
    $b = Random(1, 49, 1)
    Until $a[$b] <> 1
    $a[$b] = 1
    $z &= $b & ' '
    Next
    ConsoleWrite($z & @CRLF)

    [/autoit]

    Mega

    • Offizieller Beitrag

    Verdammt! Die ist noch schneller. :)

    Ergebnis bei 50.000 Durchläufen:
    autoit.de/wcf/attachment/1959/

    Damit gehst Du wieder in Führung. Glückwunsch!

    • Offizieller Beitrag

    Beim nachdenken über weitere Optimierungsmöglichkeiten ist mir eine ziemlich kuriose Idee in den Sinn gekommen.
    Das Script funktioniert auch, ist aber leider relativ langsam. Als zusätzlichen 'Weg nach Rom' will ich das Script hier aber trotzdem mal zum besten geben:

    [autoit]


    Global $z = '', $h = '$r<>0'
    For $i=0 To 6
    Do
    $r = Random(1,49,1)
    Until Execute($h)
    $z &= $r & ' '
    $h &= ' And $r<>' & $r
    Next
    MsgBox(0,'',$z)

    [/autoit]
    • Offizieller Beitrag

    Okay,

    einen habe ich noch :D

    [autoit]

    Global $p, $z, $s, $a[50] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
    For $i = 49 To 43 Step -1
    $p = Random(1, $i, 1)
    $z = $a[$p]
    $a[$p] = $a[$i]
    $s &= $z & ' '
    Next
    ConsoleWrite($s & @CRLF)

    [/autoit]

    Mega

    • Offizieller Beitrag

    Ok, da wir uns ja nun darauf beschränken einfach 7 Zahlen zu ziehen, statt die Zusatzzahl extra zu benennen, habe ich meine Neue Version dahingehend angepasst und komme Deiner Spitzenposition etwas näher. :)

    Dein Script habe ich mal etwas gekürzt in den Test aufgenommen:

    [autoit]


    Global $p, $s, $a[50] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
    For $i = 49 To 43 Step -1
    $p = Random(1, $i, 1)
    $s &= $a[$p] & ' '
    $a[$p] = $a[$i]
    Next
    ConsoleWrite($s & @CRLF)

    [/autoit]

    Außerdem habe ich mal meine Execute-Version mit aufgenommen und einen neuen Test mit 50.000 Durchläufen gemacht:
    HEX Color3.au3
    Deine Array-Version brachte es immerhin auf den 3. Platz.
    Meine Execute-Version ist gleichauf mit meiner alten Version.

    • Offizieller Beitrag

    Ok! Hier der ultimative Test!

    Ich beschränke das mal auf unsere Scripte (mein Execute-Script habe ich rausgehauen und unsere Ursprungsscripte auf nur Zahlenausgabe gekürzt).
    Alle Tests mit 'nur' 10.000 Durchläufen:

    10 Zahlen aus 49:
    tristatestuff.zip

    20 Zahlen aus 49:
    Treeview-InstallScript.au3

    30 Zahlen aus 49:
    Beep Komponist 2.1.0.au3

    40 Zahlen aus 49:
    Beep Komponist 2.1.0.exe

    Erst ab 30 Zahlen überholt Deine 'Array-Version' Deine 'Neue Version'. Erstaunlich finde ich aber, dass Deine 'Neue Version' mit dem Array-Nachher-Vergleich so gut mithält. Selbst bei 40 Zahlen.