Hallo zusammen,
was ist schneller:
- String ständig mit $string &= $variable & "|" befüllen
zum Schluss $array = stringsplit($string, "|") - arrayadd($array, $variable)
LG FKFK
Hallo zusammen,
was ist schneller:
LG FKFK
Hi,
wenn du viel Wert auf Performance legst würde ich die ganz normale Array-Variante vorziehen.
_ArrayAdd(...) braucht (wahrscheinlich) aufgrund des ständigen ReDims extrem lange, StringSplit(...) muss den Datensatz zum Schluss nochmals abarbeiten, deshalb ist auch diese Variante (etwas) langsamer als die Array Version.
Hier mal ein Testskript, _E3() ist wie schon geschrieben am schnellsten:
#include <Array.au3>
[/autoit] [autoit][/autoit] [autoit]Global Const $iPasses = 10000
[/autoit] [autoit][/autoit] [autoit]_E1()
_E2()
_E3() ; => Am schnellsten!
Func _E1()
Local $hTimer, $sString, $aArray
$hTimer = TimerInit()
For $i = 0 To $iPasses
$sString &= $i & '|'
Next
$aArray = StringSplit($sString, '|', 2)
MsgBox(64, 'Finished E1 (StringSplit)', 'Time (ms): ' & Round(TimerDiff($hTimer), 2))
;_ArrayDisplay($aArray)
EndFunc
Func _E2()
Local $hTimer, $aArray[1]
$hTimer = TimerInit()
For $i = 1 To $iPasses
_ArrayAdd($aArray, $i)
Next
MsgBox(64, 'Finished E2 (_ArrayAdd)', 'Time (ms): ' & Round(TimerDiff($hTimer), 2))
;_ArrayDisplay($aArray)
EndFunc
Func _E3()
Local $hTimer, $aArray[$iPasses]
$hTimer = TimerInit()
For $i = 0 To $iPasses-1
$aArray[$i] = $i
Next
MsgBox(64, 'Finished E3 (Array)', 'Time (ms): ' & Round(TimerDiff($hTimer), 2))
;_ArrayDisplay($aArray)
EndFunc
Danke für das anschauliche Beispiel
Da die Arraygröße erst am Schluss bekannt ist, ist stringsplit wohl die beste Lösung.
Da die Arraygröße erst am Schluss bekannt ist, ist stringsplit wohl die beste Lösung.
Nicht unbedingt. Du kannst doch sicher abschätzen, ob es 100.000 oder 1.000.000 Einträge werden. Erstelle ein Array am Beginn, das auf jeden Fall größer ist als die zu erwartende Anzahl an Einträgen. Den Zähler für die Anzahl Elemente erhöhst du bei jedem neuen Element und verwendest ihn dann als Index für den Eintrag im Array (Achtung: Index beginnt bei 0). Nach dem letzten Element-Eintrag schneidest du mit ReDim die überzähligen Arrayelemente ab. Du kannst auch den Zähler an Position [0] im Array führen, wenn die Anzahl der Elemente im weiteren von Bedeutung ist (erspart dir ein UBound ;)).
Global $array[100000] = [0] ; Zähler an [0] führen
[/autoit] [autoit][/autoit] [autoit]For $i = 0 To $iPasses
$array[$array[0]] = $i ; Eintrag an aktueller Zählerposition
$array[0] += 1 ; Zähler um eins erhöhen
Next
ReDim $array[$array[0]]
[/autoit]In diesem Fall wird man aber wahrscheinlich gerade langsamer sein, da ja jedesmal noch $Array[0] inkrementiert wird:
Global Const $N = 10000
[/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]$iT = TimerInit()
Global $a_R[1e6]
For $i = 1 To $N
$a_R[0] += 1
$a_R[$a_R[0]] = $i
Next
ReDim $a_R[$N+1]
$iT = TimerDiff($iT)
ConsoleWrite(StringFormat("%15s:\t%6.2f ms\n", "Array + Redim ", $iT))
$iT = TimerInit()
Global $s_S = ""
For $i = 1 To $N
$s_S &= $i & '|'
Next
Global $a_R = StringSplit(StringTrimRight($s_S, 1), "|")
$iT = TimerDiff($iT)
ConsoleWrite(StringFormat("%15s:\t%6.2f ms\n", "String & ", $iT))
$iT = TimerInit()
Global $a_R[$N+1] = [$N]
For $i = 1 To $N
$a_R[$i] = $i
Next
$iT = TimerDiff($iT)
ConsoleWrite(StringFormat("%15s:\t%6.2f ms\n", "Array ", $iT))
Mal abgesehen davon das nicht nur die "Schnelligkeit" ein optimales Programm ausmacht sondern auch der Speicherverbrauch.
Und einfach so ein Array mit Mondgröße zu initialisieren spricht dem ziemlich entgegen.
FKFK:
Stringsplit fetzt - nimm es.
In Zeile 8 ist es praktischer, wenn man als Index $i nimmt oder?
Ja ist es.
Hier sollte es lediglich simulieren, dass sporadisch Daten hinzukommen weswegen man dann immer auslesen müsste wieviele Elemente schon vorhanden sind.