Objekte übergeben

  • Hallo zusammen,

    ich habe zwei Scripts, welche beide mit Objekten (Dictionary.Scripting) arbeiten.

    Lasse ich beide Scripte einzeln laufen, so braucht jedes Script ca. 1 Minute. Hintereinander ausgeführt also ca. 2 Minuten.
    Nun möchte ich beide Scripte "parallel" ausführen lassen. Ich habe beide einzeln mal als EXE erzeugt und gleichzeitig ausgeführt. Sie sind beide nach total 1 Minute 1 Sekunde fertig. Also eine enorme Zeitersparnis, wenn ich beide parallel ausführen lasse! (Später wird dann noch mehr indiziert, so dass die Ausführdauer massiv länger ist!)

    Da ich in einem weiteren Script die Dictionary weiterverarbeiten sollte, wollte ich nach einer Möglichkeit fragen, die Objekte aus den einzelnen (externen) Funktionen zu meinem Hauptprogramm zu übergeben. (Muss ich ja, denn AutoIt kann keine Tasks "parallel" ausführen).
    Die Objekte in Arrays abzufüllen und zu übergeben, oder gar in einem File zu speichern, kommt aus Zeitgründen nicht in Frage, da momentan etwa 7 Millionen Einträge pro Dictionary vorhanden ist. (Deshalb auch keine Arrays, weil dort bei 16 Millionen Einträgen schluss ist. Ich brauche später vermutlich 20 - 30 Millionen Einträge)

    Wie ist das Möglich? Oder können die wie Variablen übergeben werden? (Beispiele dazu habe ich in diesem Forum gefunden)

    Vielen Dank
    Veronesi

  • Also was ich noch versucht habe, ist das Objekt per Parameter bei ShellExecute zu übergeben.
    Klappt leider nicht. (War ja eigentlich zu erwarten)

    Hat jemand eine Idee wie man Objekte (oder vielleicht später auch mal Fenster handles) übergeben könnte?

  • Hatte ein ähnliches problem. Sehr viele Daten in kurzer zeit verarbeiten. Sehr gute Möglichkeit bei diesem Problem ist die RAM DB von SQLite.
    Vorteil: man kann komplexe Tabellen bauen, diese miteinander verknüpfen und durch die Indexerstellung geht die Suche in der DB auch noch schneller.
    Hoffe es hilft dir weiter.

  • hi, mit AutoItObject kannst du ein Objekt freigeben, sodass andere Prozesse Zugriff darauf haben.

    Spoiler anzeigen
    [autoit]

    If $CMDLINE[0] <> 0 Then
    $o1 = ObjGet("AutoIt.Receiver")
    $o1("blub") = 123
    MsgBox(0, '', "OK")
    Exit
    EndIf

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

    #include<AutoItObject.au3>
    _AutoItObject_Startup()
    $o = ObjCreate("Scripting.Dictionary")
    _AutoItObject_RegisterObject($o, "AutoIt.Receiver")

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

    ShellExecuteWait(@AutoItExe, $CMDLINERAW & " --io", @WorkingDir)

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

    MsgBox(0, '', $o("blub"))
    $o = 0
    _AutoItObject_Shutdown()

    [/autoit]


    Du könntest sogar so weit gehen und eine Art Pipeline machen:
    Stufe 1: In den beiden Subskripten jeweils einen Teil berechnen
    Stufe 2: Die Einträge im Hauptskript weiterverarbeiten.
    Stufe 2 wird immer ausgeführt, sobald genügend Daten im Dictionary sind. Bei Millionen von Datensaätzen würde ich versuchen, die Datencaches möglichst leer zu halten ;)

    2 Mal editiert, zuletzt von progandy (8. August 2011 um 13:14)

  • Hallo Edmann

    Das mit der RAM Datenbank habe ich hier Thread schon probiert - leider ohne Erfolg.

    Der Tipp von Progandy tönt - wie zu erwarten war - sehr verheißungsvoll.

    Leider habe ich mit eurem Projekt AutoItObject (von der Schweizer Fachhochschule??) noch nie etwas gemacht. Obwohl ich früher auch dort in der Schule war ;)

    Zudem bin ich jetzt am A.... der Welt ohne Notebook. Kann es also frühestens in 2-3 Wochen testen.

    Eigentlich setze ich sehr ungerne UDF oder Funktionen ein, welche ich nicht selbst geschrieben habe, oder zumindest nicht verstehe...

    Aber eine andere Möglichkeit wird's wohl nicht geben?? Ich muss "nur" Objekte zwischen AutoIt Programmen übergeben können. Alle anderen Funktionen Eures Projektes bräuchte ich sowieso nicht.....

    Vielen Dank schon mal für den sehr wertvollen Tipp!
    Gruß, Veronesi

  • Welche Schweizer Fachhochschule?
    Du kannst die UDFs auch gerne selbst erstellen :D Das ist aber einiges an Arbeit und benötigt das Verständnis der COM-interna. Da bin ich auch nicht der beste sondern trancexx ;)

  • Die ETH Zürich (Eidgenössische teschnische Fachhochschule)
    AutoItObject

    Aber ist ja egal, von woher es kommt.

    Bei Deinem Beispielscript, funktioniert das auch so, wenn die ersten 6 Zeilen in einem anderen (AutoIt) Programm stehen?
    Natürlich muss dann unten das entsprechende Programm aufgerufen werden, klar. Und das Hauptprogramm (unten) muss auch laufen, solange das obere läuft.

    Würde das klappen?
    Dann könnte ich das wirklich mal testen.

    Danke + Beste Grüsse
    Veronesi

  • Ach so meinst du das. Die ETH stellt nur die Webseite und SVN zur Verfügung. Da gibt es keine Verbindung ;) Origo ist eine kostenlose Hostingplattform für Softwareprojekte.

    Klar funktioniert das auch in unterschiedlichen Skripten. Du siehst ja, dass das Skript 2mal gestartet wird, einmal wird der Server ausgeführt und das 2. mal dann die Daten eingetragen. Die Objektoperationen könnten aber eventuell etwas langsamer werden.

  • Das werde ich auf jeden Fall mal testen und Geschwindigkeitsvergleiche machen.
    Auch wenn die Objektoperationen etwas langsamer werden, ist es u.U. immer noch schneller als wenn ich alles sequentiell ausführe!

    Vielen Dank!
    Grüße, Veronesi

  • Hi
    Ich habe nun mal mit einem kleinen Testprogramm den Geschwindigkeitsvergleich gemacht.
    Leider sind die Objektoperationen aber um Faktoren langsamer...

    Jetziges Programm: 35ms
    Programm mit AutoItObject: 3625ms

    Das ist für mich leider zu langsam. Muss ich wohl eine andere Lösung suchen.

    PS: Momentan habe ich leider mein Testscript nicht mehr, kann es also nicht posten.

  • So, ich habe nun wieder mal kurz ein Testprogramm erstellt:

    test.au3
    [autoit]

    #include "AutoItObject.au3"
    $o = ObjCreate("Scripting.Dictionary")

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

    _AutoItObject_Startup()
    _AutoItObject_RegisterObject($o, "AutoIt.SourceFiles")

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

    $Timer = TimerInit()
    $PID = Run('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & @ScriptDir & '\' & 'test2.au3' & '"', @WorkingDir)

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

    While ProcessExists($PID)
    Sleep(10)
    WEnd

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

    MsgBox(0, '', TimerDiff($Timer))
    $o = 0
    _AutoItObject_Shutdown()

    [/autoit]
    test2.au3
    [autoit]

    $o1 = ObjGet("AutoIt.SourceFiles")
    ;~ $o1 = ObjCreate("Scripting.Dictionary")

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

    For $i = 1 To 1000
    $o1.Add($i, $i)
    Next
    Exit

    [/autoit]

    Lässt man nun test.au3 laufen, so wird die Endzeit angezeigt.
    Danach muss man in test2.au3 die zweite Zeile wieder aktivieren (Kommentar entfernen) und danach nochmals test.au3 ausführen.
    Dieses Mal ist es massiv schneller.

    Logisch, da nun die Objektoperationen nicht noch durch die AutoItObject DLL müssen.....
    Leider ist das für mich so viel zu langsam... :(