Skriptlaufzeit differiert stark

    • Offizieller Beitrag

    Hi,
    ich hab mir eine Testumgebung erstellt, in der ich meine Algorithmen zum Primzahlbattle teste (nicht wundern, wegen der Zeiten: 1,5 GHz).
    Dabei ist mir etwas seltsames aufgefallen:
    - die Laufzeitabweichungen sind bei einem Skript max. 14%, beim anderen bis zu 25% !!
    - führe ich die Skripts in einer Schleife immer abwechselnd aus ist die Abweichung am gerinsten
    - wiederholte Ausführung eines Skriptes führt zu den stärksten Abweichungen

    Messergebnisse
    Testumgebung
    [autoit]

    #include <Array.au3>

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

    Local $n_Schleife = 10
    Local $a_Time1[$n_Schleife]
    Local $a_Time2[$n_Schleife]
    Local $t, $sMess = ''

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

    For $i = 1 To $n_Schleife
    $t = TimerInit()
    _GetPrime_1()
    $a_Time1[$i -1] = Round(TimerDiff($t)/1000, 3)
    $t = TimerInit()
    _GetPrime_2()
    $a_Time2[$i -1] = Round(TimerDiff($t)/1000, 3)
    $sMess &= '[' & StringFormat('%0' & StringLen($n_Schleife) & 'd', $i) & '] ' & StringFormat('%.3f', $a_Time1[$i -1]) & ' | ' & StringFormat('%.3f', $a_Time2[$i -1]) & @TAB
    If Mod($i, 3) = 0 Or $i = $n_Schleife Then
    ConsoleWrite($sMess & @CRLF)
    $sMess = ''
    EndIf
    Next

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

    Local $av1 = 0, $av2 = 0
    For $i = 0 To $n_Schleife -1
    $av1 += $a_Time1[$i]
    $av2 += $a_Time2[$i]
    Next
    ConsoleWrite(@CRLF & '=== Algorithmus 1 ===' & @CRLF)
    ConsoleWrite('Min: ' & @TAB & StringFormat('%.3f', _ArrayMin($a_Time1, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMin($a_Time1, 1)/Round($av1/$n_Schleife, 3)*100, 2) & '%' & @CRLF)
    ConsoleWrite('Max: ' & @TAB & StringFormat('%.3f', _ArrayMax($a_Time1, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMax($a_Time1, 1)/Round($av1/$n_Schleife, 3)*100, 2) & '%' & @TAB & '- vom Min: ' & Round( _ArrayMax($a_Time1, 1)/_ArrayMin($a_Time1, 1)*100, 2) & '%' & @CRLF)
    ConsoleWrite('Mittel: ' & StringFormat('%.3f', Round($av1/$n_Schleife, 3)) & @CRLF & @CRLF)
    ConsoleWrite('=== Algorithmus 2 ===' & @CRLF)
    ConsoleWrite('Min: ' & @TAB & StringFormat('%.3f', _ArrayMin($a_Time2, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMin($a_Time2, 1)/Round($av2/$n_Schleife, 3)*100, 2) & '%' & @CRLF)
    ConsoleWrite('Max: ' & @TAB & StringFormat('%.3f', _ArrayMax($a_Time2, 1)) & @TAB & '- vom Mittel: ' & Round( _ArrayMax($a_Time2, 1)/Round($av2/$n_Schleife, 3)*100, 2) & '%' & @TAB & '- vom Min: ' & Round( _ArrayMax($a_Time2, 1)/_ArrayMin($a_Time2, 1)*100, 2) & '%' & @CRLF)
    ConsoleWrite('Mittel: ' & StringFormat('%.3f', Round($av2/$n_Schleife, 3)) & @CRLF & @CRLF)

    [/autoit]


    Vielleicht könnt ihr ja mal testen, wie das bei euch aussieht - beliebige Funktionen in die Testumgebung einsetzen und los. Vielleicht ist es ja auch nur bei meinem Schlepptop so. :wacko:
    Die verwendeten Funktionen verwenden übrigens ausschließlich lokale Variablen.

  • Wenn wir davon ausgehen dass die Schwankungen zufälliger Natur sind und somit die Messwerte einer näherungsweisen Normalverteilung folgen (kann man auch testen) dann kannst du als verlässlicheres Maß für die Streuung die Standardabweichung berechnen statt nur, eher unwichtige, Min & Max-Werte zu vergleichen.

    Mal als Beispielumgebung:

    Spoiler anzeigen
    [autoit]

    Global $N = 1000
    Global $Mean1, $Mean2, $StdAbw1, $StdAbw2
    Global $Sum1, $Sum2, $QuSum1, $QuSum2
    Global $Timer, $sumTimer

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

    For $i = 1 To $N
    $Timer = TimerInit()
    ;Algorithmus 1:
    MemGetStats()
    $Timer = TimerDiff($Timer)
    $Sum1 += $Timer
    $QuSum1 += $Timer^2

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

    $Timer = TimerInit()
    ;Algorithmus 2:
    ProcessGetStats()
    $Timer = TimerDiff($Timer)
    $Sum2 += $Timer
    $QuSum2 += $Timer^2
    Next

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

    ;Mittelwerte berechnen
    $Mean1 = $Sum1 / $N
    $Mean2 = $Sum2 / $N

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

    ;Standardabweichungen berechnen
    $StdAbw1 = $QuSum1/$N - $Mean1
    $StdAbw2 = $QuSum2/$N - $Mean2

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

    ;Genauigkeit von TimerInit-TimerDiff
    For $i = 1 To 10000
    $sumTimer += TimerDiff(TimerInit())
    Next

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

    ConsoleWrite("-------- Algorithmus 1 ----------------" & @CRLF & "Mittelwert: " & $Mean1 & @CRLF & "Standardabweichung: " & $StdAbw1 & @CRLF & @CRLF)
    ConsoleWrite("-------- Algorithmus 2 ----------------" & @CRLF & "Mittelwert: " & $Mean2 & @CRLF & "Standardabweichung: " & $StdAbw2 & @CRLF & @CRLF)
    ConsoleWrite("Genauigkeit TimerInit-TimerDiff: " & $sumTimer / 10000 & " ms" & @CRLF)

    [/autoit]


    Und ja - es kann schon tatsächlich sehr schwanken.
    In diesem Beispiel ist bei mir bei Funktion 1 die Standardabweichung um den Faktor 30 geringer als der eigentliche Mittelwert während es bei der 2. Funktion sogar größer ist als der Messwert!
    Das lässt darauf schließen dass bei der 2. Funktion deutlich mehr zufällige Faktoren dazu kommen als bei der ersten - mehr kann man erstmal nicht sagen da man ja keinen Einblick in die Funktionen hat.
    Wenn die Messwerte sehr klein werden solltest du auch mitbeachten das die Genauigkeit von TimerInit-TimerDiff die Messwerte noch zusätzlich verfälscht.