Array vorne erweitern

  • Ok Ok, der Titel ist jetzt .... etwas komisch.

    Am besten ich fange mal vorne an. Aktuell habe ich ein Script, welches sich der Reihe nach durch unterschiedliche Datenbanken anmeldet, dort immer den gleichen SQL Select ausführt. Das Ergebnis steckt dann ja in einem Array. Zusätzlich habe ich noch einen Counter laufen. Mit der Information "Counter", "Datenbank" und Array baue ich eine HTML Seite zusammen. Bei ca. 10000 Datensätzen dauert das leider eine gewisse (zu lange) Zeit.

    Jetzt habe ich herausgefunden, wie ich mit einem JavaScript die HTML Seite sehr viel schneller aufbauen kann. Dazu lade ich das Array komplett in die Zwischenablage, verändere dort noch Strings (aus "|" wird ein @TAB) und speichere das mit FileWrite in eine Textdatei. Diese Textdatei wird dann von dem JavaScript ausgelesen und baut dann die HTML Seite auf. Geht im Vergleich zur ersten Methode sauschnell.

    Da ich jetzt nicht mehr Zeilenweise durch das Array gehe um die HTML Seite zu generieren, suche ich eine Möglichkeit, das Array in der Zwischenablage "vorne" zu erweitern. Schön wäre es, wenn ich dort die Zeilennummern (Counter) noch angezeigt bekomme. Was aber wichtiger wäre, sind die Datenbanken, d.h. ich finde ja eventuell in unterschiedlichen Datenbanken Informationen und muss dann in der HTML optisch darstellen, aus welcher Datenbank der Datensatz gefunden wurde.

    Das Array, welches in die Zwischenablage kommt und dort dann noch Stringmanipuliert wurde, sieht z.B. so aus:

    Code
    ID	EN-SN NR	TYPE	RELEVANT
    70269	ENBASCK09066	EN	1
    60193	ENBASCK09005	EN	0
    143906	ENBASCK09050	EN	1
    1626	ENBASCK09033	EN	1

    Ziel wäre dann sowas

    Code
    Counter	DB	ID	EN-SN NR	TYPE	RELEVANT
    1	DB1	70269	ENBASCK09066	EN	1
    2	DB1	60193	ENBASCK09005	EN	0
    3	DB2	143906	ENBASCK09050	EN	1
    4	DB3	1626	ENBASCK09033	EN	1


    Leider habe ich keine Ahnung, wie ich hier rausgehen soll. Ziel muss halt sein, das es schneller geht, als Zeilenweise die HTML Datei aufzubauen.

    Gruß und Dank

    C4F

  • Magst du noch deinen bisherigen Quellcode mit uns teilen? :)
    Ich schätze du machst dort einige sachen die viel Zeit benötigen und deshalb dauert es so lange.

    10000 Zeilen kann man eigentlich ziemlich schnell in eine HTML-Datei umwandeln.
    (Ich hab auch schon 50000+ Einträge aus einer SQLite DB in eine Listview in wenigen Sekunden eingetragen)

    Ein Array zu erweitern ist generell eine blöde Idee, da es dann jedesmal neu erstellt wird. Wenn du weißt, wie viele Datenbanken du durchläufst erstellt man das Array direkt in der Größe und trägt die Daten dann dort ein.
    Das Problem ist, dass beim erweitern das gesamte Array in ein neues eine Reihe größeres Array kopiert wird. Das dauert lange. Sind halt 9999 kopiervorgänge mit je n-1 Einträgen, die kopiert werden müssen.

  • Hallo Kanashius,

    vielen Dank für die schnelle Antwort.

    Hier mal ein Teilauszug aus meinem Script, damit Du siehst was ich so treibe

    In der Funktion _HTMLbauen() wird das Grundgerüst angelegt.

    Spoiler anzeigen

    Ab der Codezeile "If GUICtrlRead($idCheckbox01) = 4 Then" möchte ich die HTMLSeite nach der neuen Methode bestücken, in der Codezeile "
    ElseIf GUICtrlRead($idCheckbox01) = 1 Then" bestücke ich noch nach der alten Methode.

    Hier jetzt der gekürzte Block, wo ich die Datenbank abfrage und die HTMLSeite entsprechend weiter baue

    Spoiler anzeigen

    Im Block "If GUICtrlRead($idRadio_5) = 1 Then ; Massensuche ist aktiviert" erstelle ich herkömmlich die HTML Seite, im Block " Else ; Einzelsuche ist aktiv" dann wieder optimiert.


    Gruß und Danke für die Hilfe


    C4F

  • Ich bin mir nicht ganz sicher, was du vorhast, aber das hier sollte das ganze deutlich beschleunigen:

    Vorher hast du die Datei bei jedem FileWriteLine geöffnet, 1 Zeile geschrieben geschlossen, und das immerwieder... Jetzt wird einmal geöffnet und immerweider reingeschrieben und dann geschlossen. Außerdem hab ich UTF8 bei FileOpen angegeben und die Zeile mit dem Metatag UTF8 wieder mit reingenommen. (Ist die Zeichencodierung).
    Hab außerdem etwas mit Array gearbeitet um das ganze etwas kompakter und übersichtlicher zu machen :)

    Selbe mit dem FileOpen wie hier dann auch in dem Datenbankteil. Mehr konnte ich in dem DBteil auch nicht sehen. Evtl. kann man das ClipGet noch rausbekommen, sowas ist immer recht unsicher.

  • Guten Morgen Kanashius,

    danke für die Optimierungen. Ich habe jedoch ganz weit oben in meinem Script bereits das FileOpen drin und am Ende schließe ich das dann auch wieder. Abgesehen davon, dass du mit Arrays arbeitest und das Script dadurch "aufgeräumter" wirkt (was ja nicht schlecht ist - aber für mich als ewiger Anfänger nicht so leicht lesbar), wollte ich fragen, wieso das schneller sein soll?

    Gruß C4F

    Einmal editiert, zuletzt von Code4Fun (8. Februar 2017 um 09:33)

  • Wenn du FileOpen schon benutzt, dann war das nicht ersichtlich, denn $sHTMLfile lässt auf einen String schließen (Das kleine s vorne steht für string, also text in der Variable, bei nem filehandle wäre dort ein kleines h).
    Dann brauch ich das gesamte Script um das schneller zu machen.
    Generell als Info: normal übergibt man solche FileHandle,FileNamen als Funktionsparameter. Globale Variablen werden vermieden, wenn es geht, denn das sorgt für unübersichtlichkeit.

    MfG Kanashius

  • Anhand meiner Beiträge siehst Du ja, das in mir noch ein Autoit Neuling steckt, d.h. ich mache bestimmt sehr viel falsch. Habe das Programmieren auch nie gelernt, sondern mich halt so Step by Step reingelesen und probiert usw.

    Hier also der gewünschte gesamte Code (hoffe dir wird nicht schlecht dabei <X )

    Spoiler anzeigen

    Leider funktioniert die "Autoit" Hervorhebung nicht

    Gruß und Danke

    C4F

  • Hab nen bisschen was gefunden, also erstmal zum Stil:
    Ist ziemlich unübersichtlich. ;)

    Les dich unbedingt einmal in das Thema Arrays ein. Dadurch wäre dein Script weniger als halb so groß und auch deutlich übersichtlicher.
    Immer wenn du nen Codeblock Copy&Pastest und nur kleinigkeiten änderst ist dort potential, sich wiederholenden Code zu vermeiden. Das hat auch den Vorteil, dass wenn man was ändert nur an einer Stelle was geändert werden muss und nicht überall.
    (Switch-case blöcke können auch hilfreich sein)
    Hier ein paar abschnitte in deinem Script: 88-116 (Die Controls in Arrays zu packen vereinfacht vieles, oder zumindest passender benennen.) | 147-240 | 290-339 | 347-435 |!!! 469-547 | 557-670 | 701-1048 (Die Blöcke unterscheiden sich nur in Kleinigkeiten) | 1056-1095

    Und unbedingt Funktionsparameter nutzen und keine globalen Variablen. Du änderst manchmal mittem im Script eine Variable und man hat keine Ahnung, was das ist/bringen soll (z.B. 273: $sDateiName)
    Man übergibt Variablen an eine Funktion, arbeitet damit und gibt das Ergebnis zurück. Dadurch kann man die Funktionen Seperat betrachten und beurteilen/ändern/verbessern, ohne immer das gesamte Script im Blick zu haben.

    Hoffe, die Tipps bringen dich zumindest bei deinem nächsten Projekt weiter :)

    Was die Geschwindigkeit angeht liegt das Problem daran, dass du für jeden Datenbanksatz noch eine weiter SQL-Abfrage ausführst. Das kostet recht viel Zeit.
    Das kann man kürzen, indem man die beiden Tabellen BEGLEITSCHEIN und TEILNEHMER joint und dann die Daten abfragt:
    "SELECT r.BEGLEITSCHEIN_ID, r.BGSNR, r.BEARBEITUNGSST, r.LAST_LAYER_ID, r.TEILNEHMER_ID, r.RELEVANT, r.STORNIERT, t.BEHOERDLICHE_NUMMER, t.TEILNEHMERROLLE_ID FROM BEGLEITSCHEIN r,TEILNEHMER t where r.TEILNEHMER_ID=t.TEILNEHMER_ID AND r.BGSNR like '%" & GUICtrlRead($sInput01) & "%';"
    Dann würde die BEHOERDLICHE_NR und die TEILEHMER_ROLLE mit in der ersten Abfrage stehen und könnt dort ausgelesen werden.

    Mehr konnte ich was Geschwindigeit angeht nicht entdecken. Wenn bei FileWriteLine ein Handle übergeben wird wird das die Geschwindigkeit bestimmt nicht so hochtreiben.

    Du kannst ja mal schauen, wo die Zeit bleibt, indem du mit TimerInit und TimerDiff schaust, wie viel Zeit die einzelnen Schritte brauchen (Kannst du dir mit ConsoleWrite ausgeben lassen). Damit könntest du die Problemstelle eingrenzen :)

    MfG Kanashius

  • Hallo Kanashius,

    danke für die schnelle Analyse. Ich glaube ich muss noch ganz viele Hausaufgaben machen. Könntest Du mir bitte mal einen ganz kleinen Codeschnipsel über eine Funktionssyntax hier reinpipen, damit ich das sauber verstehe. Also so in der Art .... es wird von außerhalb der Funktion was an die Funktion übergeben, diese arbeitet dann mit lokalen Variablen intern und das Ergebnis muss ja wieder irgendwie nach außerhalb der Funktion rausgepipt werden.

    Gruß und noch einen schönen Abend

    C4F

  • Nur als kleines Beispiel für Arrays und Funktionsparameter mit return und seterror: