Json

  • Hi, ich mal wieder!

    Gibt es eine Möglichkeit Json zu beschleunigen.

    Hier das sript von AspirinJunkie

    wollte die Datei Test.Json hochladen

    geht nicht (ungültige Dateiendung)



    Ich brauche nur die grünen Daten.

    Meine Frage?

    Kann man das laden nach den Daten abbrechen.

    Gruß

    Windi

  • Ich brauche nur die grünen Daten.

    Meine Frage?

    Kann man das laden nach den Daten abbrechen.

    Du kannst die Datei zum Lesen öffnen und einfach zeilenweise lesen.

    Ungefähr so:



    wollte die Datei Test.Json hochladen

    geht nicht (ungültige Dateiendung)

    Einfach zu *.txt umbenennen.

  • Hier das sript von AspirinJunkie

    Das ist ganz sicher nicht mein Skript.


    Ich verstehe noch nicht was du genau machen möchtest.
    Du fragst 30 mal(!) bei TomTom die Route zwischen 2 festen Koordinaten ab.

    Das ganze hast du in einer Funktion verpackt, welche hingegen den Namen geocode trägt - also dem Namen nach was völlig anderes macht.

    Da brauchte ich erstmal n bisschen Zeit um zu verstehen was du eigentlich machen möchtest.

    Du kannst dir die Funktionen frei benennen wie du möchtest - wenn du Verwirrung (auch bei dir) vermeiden willst dann nutze dies auch.


    Nun stellst du die Frage ob man "json" noch beschleunigen kann.

    Ich vermute der ganze Prozess dauert dir zu lange.

    Also schau ich erstmal welcher Schritt wie lange benötigt.

    Hier komme ich bei mir auf folgende ungefähre Werte:


    Request bauen und an Server senden: 5 ms

    Verarbeitung auf dem TomTom-Server: 77 ms

    Download des Returns (der JSON-Datei): 2,5 ms

    Gesamtabfrage InetRead in AutoIt mit allem drumherum: ~ 250ms

    Extraktion der Werte per Wards JSON-UDF: 650 ms


    Du hast also Recht - das Hauptproblem liegt im Parsing der JSON-Daten.

    Du nutzt hierfür offensichtlich die JSON-UDF von Ward aus dem englischen Forum.

    Ich hab mal geschaut was rauskommt, wenn man zum parsen stattdessen meine UDF nimmt und voila: 250ms!

    Das erstaunt mich nun wirklich sehr, da Wards UDF kompilierten externen Code (JSMN) ausführt und ich daher erwartet hätte dass dies meine in reinem AutoIt geschriebene UDF locker abhängt.

    Ist aber offensichtlich nicht der Fall und du würdest durch den Wechsel der UDF die Gesamtzeit etwa halbieren können.


    Jetzt bringst du einen Ansatz zur Beschleunigung in die Diskussion rein, welcher erstmal gut überlegt ist.
    Du fragst ob es möglich ist direkt beim Fund aufzuhören und nicht weiter zu parsen.
    Kurz: Mit beiden JSON-UDFs ist das erstmal so nicht möglich.

    Hierfür müsste man eine Art SAX-Parser für JSON schreiben.
    Hat noch keiner gemacht - mach ich vielleicht mal wenn ich Lust habe.

    Im nächsten Schritt könnte man das Parsing auch parallel zum Datendownload durchführen, so dass nicht erst gewartet wird bis das Ende des Downloads erreicht ist. Aber das würde hier nicht wirklich was bringen.


    Nun willst du aber nur zwei ganz bestimmte Werte haben.

    Und die Ausgangsdaten scheinen auch erst einmal ziemlich stabil auszusehen.
    In diesem Fall könnte man daher auch direkt mit StringRegExp sich diese Daten ziehen und würde enorm schneller sein.

    Wenn die Reihenfolge der beiden Werte gleich bleibt, kann man dies auch direkt mit einem einzigen RegExp-Ausdruck abfrühstücken und siehe da: Die Zeit um die Werte aus dem Return zu extrahieren beträgt nur noch 0,03 ms (ja richtig gelesen).

    Unwesentlich langsamer aber dafür stabiler wäre es die beiden Daten getrennt voneinander abzufragen - kann man noch entsprechend umschreiben.


    Wenn man dies nun aber in dein Skript mit einbaut stößt man auf ein neues Problem: Wir sind nun zu schnell!
    Denn: TomTom hat eine Einschränkung drin die nur (offensichtlich) 5 Anfragen pro Sekunde erlaubt.
    Wir sind aber schneller und schaffen nun mehr als diese.
    Daher musst du noch etwas weiter anpassen, dass entweder die Anzahl der Requests pro Sekunde von vornherein beschränkt wird oder im Fehlerfall entsprechend reagiert wird.

    Ich habe dir hierfür mal eine kleine Funktion geschrieben, mit der man sicherstellen kann dass der Aufruf nur maximal 5mal pro Sekunde geschieht.


    Alles zusammen könnte man das Skript nun folgendermaßen umschreiben.
    Beachte hierbei auch wie ich die Bezeichnungen der Funktion und Variablen geändert habe - so sollte eher klar werden was das Skript eigentlich macht:




    BugFix

    Könntest du das Thema bitte in das korrekte Unterforum "Hilfe & Unterstützung" verschieben?


    Windi

    Warum eröffnest du deine Themen grundsätzlich im Testforum? Das hat dort nichts zu suchen.

  • Hi AspirinJunkie,


    großes Lob für deine Mühen, deine Erklärung für Windi und die Verbesserungen 👍 . Mir ist beim drüber schauen noch aufgefallen, dass die optionalen Parameter von _tomtom_getRouteMetrics() unnötig sind, da sie sowieso nur in dieser Funktion verwendet werden.


    Windi:

    Wenn du diese optionalen Parameter entfernst, dann kannst du dir deine beiden globalen Variablen auch sparen und sie in der Funktion als Local verwenden.


    Schreibe gerade vom Smartphone aus, ansonsten würde ich die Code-Stellen markieren, doch du wirst dies schon finden 🤞 .


    Viele Grüße

    Sven

  • Guten Morgen,

    @Oskar

    Entschuldigung hab gedacht ich müsste immer im Testforum veröffentlichen.

    (liegt wahrscheinlich am alter, oder im Moment an Carola :)


    AspirinJunkie

    (Hilfe bei Regex) hast du mir im #38 dieses Script gesendet.


    BugFix

  • Mir ist beim drüber schauen noch aufgefallen, dass die optionalen Parameter von _tomtom_getRouteMetrics() unnötig sind, da sie sowieso nur in dieser Funktion verwendet werden.

    Es geht mir darum Windi die Grundzüge von wiederverwendbaren Code zu zeigen.
    Eine Funktion welche durch 2 Parameter universell einsetzbar ist, ist besser als eine, welche nur in einem ganz konkreten Spezialfall funktioniert.

    Was hingegen entbehrlich wäre, ist die Funktion Abstand().
    Diese ist als klassische Main-Funktion komplett parameterfrei, deterministisch und wird nur einmal aufgerufen.
    Der Inhalt dieser Funktion kann daher auch direkt im Global-Kontext geschrieben werden, da in diesem Kontext kein anderer Code zur Anwendung kommt.


    AspirinJunkie

    (Hilfe bei Regex) hast du mir im #38 dieses Script gesendet.

    Nein das habe ich nicht gepostet.

    Die damals von mir gepostete Funktion geocodeAddress macht etwas ganz anderes als die Funktion in deinem Skript.

  • Ok nur keine Aufregung war ja nicht böse gemeint.

    Bin ja für jede Hilfe froh.


    AspirinJunkie

    Wow in deinem Script ist Tempo drin.

    Denn: TomTom hat eine Einschränkung drin die nur (offensichtlich) 5 Anfragen pro Sekunde erlaubt.

    Das wusste ich auch nicht das die ausbremsen können.

    Hab mich auch schon beim Webdriver gewundert, dass ich viel mit sleep() arbeiten muss.

    Da gibt es bestimmt noch andere möglichkeiten von euch.

    Aber dazu später.


    Vielen Lieben Dank

    Windi