Hallo miteinander. Ich möchte mir gerne ein Array mit Prozessnamen erstellen lassen. Jetzt denkt ihr sicher "da ist ProcessList() das Richtige für dich!". Ist es aber leider nicht. Habe ich z. B. ein Editorfenster offen zeigt mir ProcessList() nur dass "notepad.exe" gestartet ist. Ich würde aber gerne den Namen des offenen Dokuments herausfinden, nämlich "Berechnung 1.txt" wie es auch in der Anwendungsübersicht im Taskmanager (Windows 7) angezeigt wird. Gibt es dafür eine Möglichkeit unter AutoIt?
Prozessliste mit Namen erstellen
-
Scritch -
26. Juli 2017 um 13:24 -
Erledigt
-
-
Die Anwendungsübersicht zeigt dir die Fenster an die offen sind, diese kriegst du mit WinList, dem Äquivalent zu ProcessList.
-
Meinst du sowas z.B.: ?
AutoIt
Alles anzeigen#include <Array.au3> $aWin = processlist() $c = 0 Dim $aList[0][3] for $i = 0 to ubound($aWin)-1 $sWin = _Process2Win($aWin[$i][1]) if $sWin <> -1 then $c = $c + 1 ReDim $aList[$c][3] $aList[$c-1][0] = $aWin[$i][0] $aList[$c-1][1] = $aWin[$i][1] $aList[$c-1][2] = $sWin EndIf Next _Arraydisplay($aList) Func _Process2Win($pid) If IsString($pid) Then $pid = ProcessExists($pid) If $pid = 0 Then Return -1 Local $list = WinList(), $wpid For $i = 1 To $list[0][0] If $list[$i][0] <> "" AND BitAnd(WinGetState($list[$i][1]),2) Then $wpid = WinGetProcess($list[$i][0]) If $wpid = $pid Then Return $list[$i][0] EndIf Next Return -1 EndFunc ;==> Quelle: https://autoit.de/index.php/Thread/85367-Schleife-bis-R%C3%BCckgabewert-passt/?postID=683725&highlight=_Process2Win%2528%2524pid%2529
-
klemm dir das ReDim, und mach es mit _ArrayAdd
geht vielleicht schneller -
klemm dir das ReDim, und mach es mit _ArrayAdd
geht vielleicht schnellerWie kommst du denn darauf? _ArrayAdd hat ziemlich viel Extra-Schnickschnack drum und basiert im Kern auch auf die ReDim-Funktion.
Warum sollte ich also das ganze Extrazeugs mitausführen (und eine UDF includen) obwohl ich das einfach ReDimmen kann?Tests liefern auch das gleiche Resultat, _ArrayAdd ist im Schnitt wenige Millisekunden langsamer als das selbstgemachte ReDim und nur in sehr seltenen Fällen schneller (das liegt aber am Interpreter, an der CPU, Scheduler und alles was noch so dran hängt).
AutoIt
Alles anzeigen#include <Array.au3> $tmr1 = TimerInit() $aWin = processlist() $c = 0 Dim $aList[0][3] for $i = 0 to ubound($aWin)-1 $sWin = _Process2Win($aWin[$i][1]) if $sWin <> -1 then $c = $c + 1 ReDim $aList[$c][3] $aList[$c-1][0] = $aWin[$i][0] $aList[$c-1][1] = $aWin[$i][1] $aList[$c-1][2] = $sWin EndIf Next ConsoleWrite(TimerDiff($tmr1) & @CRLF) _Arraydisplay($aList) $tmr2 = TimerInit() $aWin = processlist() $c = 0 Dim $aList[0][3] for $i = 0 to ubound($aWin)-1 $sWin = _Process2Win($aWin[$i][1]) if $sWin <> -1 then $c = $c + 1 _ArrayAdd($aList, $aWin[$i][0] & "|" & $aWin[$i][1] & "|" & $sWin) EndIf Next ConsoleWrite(TimerDiff($tmr2) & @CRLF) _ArrayDisplay($aList) Func _Process2Win($pid) If IsString($pid) Then $pid = ProcessExists($pid) If $pid = 0 Then Return -1 Local $list = WinList(), $wpid For $i = 1 To $list[0][0] If $list[$i][0] <> "" AND BitAnd(WinGetState($list[$i][1]),2) Then $wpid = WinGetProcess($list[$i][0]) If $wpid = $pid Then Return $list[$i][0] EndIf Next Return -1 EndFunc ;==> Quelle: https://autoit.de/index.php/Thread/85367-Schleife-bis-R%C3%BCckgabewert-passt/?postID=683725&highlight=_Process2Win%2528%2524pid%2529
-
_ArrayAdd ist im Schnitt wenige Millisekunden langsamer als das selbstgemachte ReDim
Kann ich bestätigen !
Durchlauf 1 : eigenes ReDim = 50.11 ms / mit _ArrayAdd = 71.92 ms
Durchlauf 2 : eigenes ReDim = 55.92 ms / mit _ArrayAdd = 74.04 ms
Durchlauf 3 : eigenes ReDim = 56.06 ms / mit _ArrayAdd = 69.50 msBei Abläufen im ms Bereich natürlich nicht 100% aussagekräftig, aber die Tendenz ist erkennbar.
Gruß Musashi
-
Bei Abläufen im ms Bereich natürlich nicht 100% aussagekräftig
Ich würde lieber die Relation zwischen den beiden betrachten und wie sich das auf größere Aufgaben skaliert.
Bei kleinen Aufgaben ist das natürlich völlig irrelevant. -
Bei mir ist _ArrayAdd immer schneller, als ReDim.
-
Bei mir ist _ArrayAdd immer schneller, als ReDim.
Guck mal in _ArrayAdd rein, dass die Funktion bei dir schneller ist der Grund den ich bereits beschrieben hatte. Zufall.
-
Jep da wird ein ReDim ausgeführt.
Aber ich denke nicht nach. Ich habe gesehen. _ArrayAdd ist schneller. Fake News @alpines! Fake News! -
Bei kleinen Aufgaben ist das natürlich völlig irrelevant.
Vielleicht so ?
AutoIt
Alles anzeigen#include <Array.au3> #include <Timers.au3> $iCounter = 5000 ; Anzahl der Elemente ; Test : _ArrayAdd Dim $aTestarray[0] $fStarttime1 = _Timer_Init() For $i = 1 To $iCounter $sText = "Zeile " & $i _ArrayAdd($aTestarray, $sText) Next $fDiff1 = TimerDiff($fStarttime1) ConsoleWrite("ArrayAdd = " & $fDiff1 & " ms"& @CRLF) If $iCounter < 1000 Then _Arraydisplay($aTestarray) ; Array nur bis 1000 Elemente anzeigen ; Test : ReDim selbst Dim $aTestarray[0] $fStarttime2 = _Timer_Init() $iC = 0 For $i = 1 To $iCounter $sText = "Zeile " & $i $iC = $iC + 1 ReDim $aTestarray[$iC] $aTestarray[$iC - 1] = $sText Next $fDiff2 = TimerDiff($fStarttime2) ConsoleWrite("nur ReDim = " & $fDiff2 & " ms"& @CRLF) If $iCounter < 1000 Then _Arraydisplay($aTestarray) ; Array nur bis 1000 Elemente anzeigen $iMsgBoxFlag = BitOr($MB_SYSTEMMODAL, $MB_ICONINFORMATION) MsgBox($iMsgBoxFlag, "Array Vergleich : ", _ "ArrayAdd = " & $fDiff1 & " ms" & @CRLF & _ "nur ReDim = " & $fDiff2 & " ms" & @CRLF )
Von der Geschwindigkeit her, sehe ich keinen wesentlichen Unterschied. Zumindest ist _ArrayAdd aber nicht gewaltig schneller - warum auch.
Gruß Musashi
-
Ich würde lieber die Relation zwischen den beiden betrachten und wie sich das auf größere Aufgaben skaliert.
Hier kann man das Skalierungsverhalten der beiden einschätzen:
ReDimVsArrayAdd.png
Wenig überraschend skalieren beide gleich da ArrayAdd ja nix anderes als ein verpacktes ReDim ist.
Da das umkopieren mit steigender Arraygröße immer aufwendiger wird ist die Skalierung exponentiell.Folgendes Messskript wurde verwendet:
AutoIt
Alles anzeigen#include <Array.au3> #Region Steps für Skalierung Global $i_Temp = 10 Global $a_Result[$i_Temp + 1][1] = [["Faktor"]] For $i = 1 To $i_Temp $a_Result[$i][0] = 2 ^ $i Next #EndRegion Steps für Skalierung #Region Globale Einstellungen Global Const $N = 1e2 Global $iT, $f_Overhead, $i_F, $s_MessName #EndRegion Globale Einstellungen #Region Overhead ; determine the overhead of loop [and optional other stuff] Global $a_Overhead[UBound($a_Result) - 1] For $i_Fac = 0 To UBound($a_Overhead) - 1 $i_FEnd = $a_Result[$i_Fac][0] $iT = TimerInit() For $i = 1 To $N Global $a_A[0] For $j = 1 To $i_F Next Next $a_Overhead[$i_Fac] = TimerDiff($iT) Next #EndRegion Overhead #Region Erste Messung ReDim $a_Result[UBound($a_Result)][UBound($a_Result, 2) + 1] $a_Result[0][UBound($a_Result, 2) - 1] = "ReDim" ConsoleWrite(StringFormat('\nStarte Messung für "%s":\n', $a_Result[0][UBound($a_Result, 2) - 1])) For $i_Fac = 1 To UBound($a_Result) - 1 $i_F = $a_Result[$i_Fac][0] ConsoleWrite(StringFormat('\t\t%d\n', $i_F)) $iT = TimerInit() For $i = 1 To $N Global $a_A[0] For $j = 1 To $i_F ReDim $a_A[UBound($a_A) + 1] $a_A[UBound($a_A) - 1] = $i Next Next $iT = TimerDiff($iT) $a_Result[$i_Fac][UBound($a_Result, 2) - 1] = ($iT - $a_Overhead[$i_Fac - 1]) / $N Next #EndRegion Erste Messung #Region Zweite Messung ReDim $a_Result[UBound($a_Result)][UBound($a_Result, 2) + 1] $a_Result[0][UBound($a_Result, 2) - 1] = "ArrayAdd" ConsoleWrite(StringFormat('\nStarte Messung für "%s":\n', $a_Result[0][UBound($a_Result, 2) - 1])) For $i_Fac = 1 To UBound($a_Result) - 1 $i_F = $a_Result[$i_Fac][0] ConsoleWrite(StringFormat('\t\t%d\n', $i_F)) $iT = TimerInit() For $i = 1 To $N Global $a_A[0] For $j = 1 To $i_F _ArrayAdd($a_A, $j) Next Next $iT = TimerDiff($iT) $a_Result[$i_Fac][UBound($a_Result, 2) - 1] = ($iT - $a_Overhead[$i_Fac - 1]) / $N Next #EndRegion Zweite Messung ; Ergebnisse in Zwischenablage für Excel sowie als ArrayDisplay ClipPut(StringReplace(_ArrayToString($a_Result, @TAB), ".", ",")) _ArrayDisplay($a_Result)
-
Von der Geschwindigkeit her, sehe ich keinen wesentlichen Unterschied. Zumindest ist _ArrayAdd aber nicht gewaltig schneller - warum auch.
Ich persönlich bevorzuge lieber die selbstgemachte ReDim-Variante, einfach aus Gewohnheit (und ich spare mir eine UDF).
In deinem Beispiel ist ReDim (3739ms) 200ms schneller (~8%), da man jedes Mal den anderen Kram aus der UDF nicht durchgeht sondern wirklich nur das Array bearbeitet.
Soll jeder es so machen wie er es am besten kann und wie er es am besten findet. 200ms sind nun wirklich kein Beinbruch.Wenig überraschend skalieren beide gleich da ArrayAdd ja nix anderes als ein verpacktes ReDim ist.
Da das umkopieren mit steigender Arraygröße immer aufwendiger wird ist die Skalierung exponentiell.War auch nicht anders zu erwarten, es kommt halt immer der konstante Teil von den Überprüfungen und dem ganzen drumherum dazu.
Bei 5000 Elementen sind das schon 200ms Unterschied bei 3739-3915ms. -
Hallo @alpines !
Ich persönlich bevorzuge lieber die selbstgemachte ReDim-Variante, einfach aus Gewohnheit (und ich spare mir eine UDF).
In deinem Beispiel ist ReDim (3739ms) 200ms schneller (~8%), da man jedes Mal den anderen Kram aus der UDF nicht durchgeht sondern wirklich nur das Array bearbeitet.Ich hoffe, wir haben uns da nicht missverstanden. Mir ging es zu keiner Zeit darum, eine der Varianten zu bevorzugen, oder Dir gar zu empfehlen - ich wollte Dich eher bestätigen . Wie ja auch die (nebenbei sehr schöne) Messgrafik von @AspirinJunkie zeigt, gibt es keine nennenswerten Unterschiede in der Laufzeit.
Fazit : Statt reiner Vermutungen gibt es jetzt nachvollziehbare Beispiele !
Gruß Musashi
-
Hi,
Weil es bisher noch keine Erwähnung fand:
Wenn eine maximale Menge bekannt (und realistisch) ist gibt es eigentlich wenig Grund überhaupt ein Redim oder _arrayAdd in der Schleife zu haben.
Man erstellt das (nicht Assoziative) Array einfach mit der größten sinnvollen Anzahl an Elementen und schneidet es sich am Ende zurecht.
Sollte die maximale Menge unbekannt oder unrealistisch groß seinkann man das Array einfach in 100, 1000, 10000... Schritten vergrößern und wenn man fertig ist ggf. wieder zurechschneiden.(siehe Beitrag 17)AutoItGlobal $iIndex = 0 Global $aArray[1000] For $i = 0 to 100000 $aArray[$iIndex] = "x" $iIndex += 1 If Not Mod($iIndex, 1000) Then ReDim $aArray[$iIndex + 1000] EndIf Next ReDim $aArray[$iIndex]
mfg
Zeitriss -
Ja, damit ist man auf jeden Fall (extrem) viel schneller. In der Regel kennt man ja das Maximum.
-
Sollte die maximale Menge unbekannt oder unrealistisch groß sein kann man das Array einfach in 100, 1000, 10000... Schritten vergrößern und wenn man fertig ist ggf. wieder zurechschneiden.
Das übliche Vorgehen hierfür ist statt einer festen Anzahl zur Vergrößerung mit einem Faktor zu arbeiten. Üblich hierfür sind 1,5 oder 2.
Die .Net-Arraylist (die man in Autoit verwenden kann) oder die Java-Arraylist arbeiten nach diesem Prinzip.
Bei .Net ist der Faktor glaube ich 2, auch bei der C++-Arraylist beim gcc-Compiler während er bei der Java-Arraylist 1.5 beträgt.
Ist halt eine Frage des Ausgleich zwischen Performance und verschwendeten Platz.Für AutoIt habe ich das Prinzip (Faktor=2) auch schon mal umgesetzt: DynArray-UDF
-
Hallo @Zeitriss !
Weil es bisher noch keine Erwähnung fand:
Wenn eine maximale Menge bekannt (und realistisch) ist gibt es eigentlich wenig Grund überhaupt ein Redim oder _arrayAdd in der Schleife zu haben.
Man erstellt das (nicht Assoziative) Array einfach mit der größten sinnvollen Anzahl an Elementen und schneidet es sich am Ende zurecht.Das fand wahrscheinlich daher keine Erwähnung, weil es um eine eher theoretische Spielerei ging, also :
"Ist das manuelle ReDim schneller bzw. langsamer, als der identisch gestaltete Aufruf von _ArrayAdd ?"Auf die Praxis bezogen, hast Du natürlich völlig recht.
Kein Mensch würde Arrays in Einerschritten redimensionieren, schon gar nicht, wenn die maximale Anzahl der Elemente vorher bekannt ist .Gruß Musashi
-
Kein Mensch würde Arrays in Einerschritten redimensionieren, schon gar nicht, wenn die maximale Anzahl der Elemente vorher bekannt ist
Aber ja doch. Ich hatte schon diese glorreiche Idee.
Ich hatte ein Array und wollte da neue Elemente aus einem anderen Array hinzufügen. Dann habe ich in eine Schleife eingefügt "Wenn Bedingung zutrifft dann _ArrayAdd".
Am Tempo habe ich gesehen, dass das Mist ist. Aber mein Intellekt hat nicht ausgereicht, mir das vorher auszurechnen.PS: Ich bestehe auf Menschsein.
-
Hi,
hast natürlich recht wenn man eine völlig unbekannte Menge hat macht es natürlich wenig Sinn das Array in statischen Schritten zu vergrößern, da ist ein Faktor natürlich konsequenter.
Hatte ich mir wohl falsch angewöhnt.@Musashi
Ich bezog mich mehr auf das Script von svarts und den Vorschlag von olfibits, für eure Diskusion ist das natürlich völlig irrelevant@autoiter
Tut mir leid:Mensch
...
Bedeutungen:[1] ein Lebewesen; Spezies, der Klasse der Säugetiere angehörend, die sich durch folgende besondere Eigenschaften auszeichnet: aufrechter Gang, Sprache, Erfindertum, Vorausdenken und Nachahmung
da haben wir beide wohl nur 4/5
mfg Zeitriss
-