• Hi.

    Ich habe jetzt erst mal einen Workaround eingebaut. Ich musste neben Japanisch und Hebräisch auch Chinesisch und Russisch raus nehmen, damit die Geschichte immer sauber durch läuft. Die beiden letzten Sprachen sind beim Aerosmith- Beispiel nicht vorhanden gewesen, aber z.B. bei Led Zeppelin,. womit ich später auch getestet habe. Erst nachdem ich alle 4 Sprachen entfernt habe, hat es ohne Crash funktioniert...

  • Ich bin dran wird aber wohl noch ne Weile dauern, da das Debugging in dem Fall echt eklig ist.

    Hab ein paar Vermutungen und auch schon einen ersten Bug gefunden.
    Dürfte die nächsten Tage aber hinreichend Zeit dafür fnden (Quarantäne - Yeah!).

  • (Quarantäne - Yeah!).

    Oh je... Hoffentlich nicht wirklich infiziert... Falls doch, auf jeden Fall gute Besserung und einen harmlosen Verlauf.


    Ich bin dran

    Danke.



    wird aber wohl noch ne Weile dauern

    Ist nicht so schlimm. Wenn es denn mal fertig ist, kann ich den Workaround binnen Sekunden wieder entfernen... Bis dahin läuft es erst mal ohne diese 4 Sprachen, was mich selbst natürlich nicht wirklich stört, aber andere User des Programms aus den entsprechenden Ländern vermutlich dann doch...

  • Na das war ja mal ekelhaft zu debuggen...

    Problem war den Fehler überhaupt erst einmal zu detektieren.

    Ursache war ein Stack-Overflow bei der PCRE-Engine aufgrund einem zu exzessiven Backtracking bei langen Strings.

    Die Behebung war dann ein Klacks: Einfach ein + hinzufügen (um einen Quantifier possesiv zu machen).


    Jetzt sollte es aber auch mit deiner Aerosmith_Lesbar.json klappen.

    Selbst die Aerosmith.json parst er nun, obwohl die mir jeder JSON-Validator mir die um die Ohren haut.


    Als Nebeneffekt sollte auch die Performance wieder ein Stück gestiegen sein.

  • Ich habe mir meine Google-Timline exportiert und als Zip-Archiv auf meinem PC gespeichert. Die daraus entpackte Datei Standortverlauf.json ist bei mir derzeit etwa 70 MB groß und wenn ich die an _JSON_Parse übergebe, passiert auf meinem I7 960 auch nach mehreren Stunden scheinbar absolut nichts... außer, dass die CPU-Last durch das Parsen von 20% auf ca. 50% (± 10%) steigt... ich habe dann nach über 6 Std. abgebrochen.

    Start...: 17:17:22

    Kill....: 23:44:38


    Google-Timline (Zeitachse) muss im Google-Account erst aktiviert werden, damit es nutzbar ist!

    Google-Timline exportieren: https://takeout.google.com/set…t/custom/location_history


    Edit: Die JSON-Dateien haben als Zeilenumbruchzeichnen alle nur ein LF... aber das scheint kein Problem zu sein.

  • Das Skript hängt tatsächlich nicht sondern ist wirklich so langsam.


    Der Grund ist folgender: In der UDF wird der String schrittweise mit StringRegEx auseinander genommen.

    Das heißt also zig einzelne Aufrufe an StringRegExp() wo jedesmal der riesen String an die Funktion übergeben wird.

    Hierbei wird jedoch nicht einfach nur der Pointer auf den String übergeben sondern anscheinend(!) eine lokale Kopie des Strings erzeugt und übergeben.

    Mal ein einfaches Skript zur Demonstration:

    Hier sieht man, dass die Ausführungsgeschwindigkeit direkt von der Größe des Strings abhängt obwohl das Pattern selbst nur das erste Zeichen auswertet.

    Wenn nun also jedes RegEx - egal wie simpel es ist - eine halbe Sekunde braucht, dann ist klar dass dies bei 100.000en Aufrufen die für eine solche Datei nötig wären, unheimlich hohe Bearbeitungszeiten herauskommen.


    So - wie nun also damit umgehen? Das Grundproblem liegt außerhalb meines Einflussbereiches.

    Ich werde das eventuell mal aufbereiten und im englischen Forum vortragen - in der Hoffnung, dass intern auf by Reference umgestellt wird.

    Bei StringLeft() oder StringMid() hat man dieses Phänomen übrigens nicht.

    Oder eine ganz andere Lösung die ich noch nicht sehe.


    Für so große JSON-Strings sollte man daher auf AutoIt-externe Lösungen zurückgreifen.

    Für diesen Fall gibt es z.B. die >>JSMN-basiert UDF<<. Diese verwendet JSMN als Parser. Das Parsing wird also nicht von AutoIt erledigt.

    Des Weiteren wird auch nicht der ganze String in native Datentypen gecastet sondern es wird lediglich eine Liste erzeugt wo an welcher Stelle welche Datentypen stehen.

    So ist die Struktur erstmal ganz fix geparsed und die Objekte selbst werden erst gecasted wenn wirklich auf sie zugegriffen wird.

    Kurz und knapp: Das ist deutlich fixer als eine AutoIt-basierte Lösung wie bei mir und sollte insbesondere bei derart großen Files die passende Alternative darstellen.


    Außer natürlich es findet sich noch ne Lösung für die Übergabe der großen Strings an StringRegExp() ;)

  • So kann man sehr gut sehen, wie der Zeitbedarf mit zunehmender Stringlänge ansteigt:

    Code: Ausgabe
     1/10 Zeitbedarf StringRegExp($sString, "^.") bei           10 Zeichen (  10 Bytes):    0.005 ms
     2/10 Zeitbedarf StringRegExp($sString, "^.") bei        10240 Zeichen (   10,0 KB):    0.048 ms
     3/10 Zeitbedarf StringRegExp($sString, "^.") bei     10485760 Zeichen (   10,0 MB):   13.381 ms
     4/10 Zeitbedarf StringRegExp($sString, "^.") bei     20971520 Zeichen (   20,0 MB):   20.047 ms
     5/10 Zeitbedarf StringRegExp($sString, "^.") bei     31457280 Zeichen (   30,0 MB):   34.832 ms
     6/10 Zeitbedarf StringRegExp($sString, "^.") bei     41943040 Zeichen (   40,0 MB):   39.172 ms
     7/10 Zeitbedarf StringRegExp($sString, "^.") bei     52428800 Zeichen (   50,0 MB):   46.496 ms
     8/10 Zeitbedarf StringRegExp($sString, "^.") bei    104857600 Zeichen (    100 MB):  101.790 ms
     9/10 Zeitbedarf StringRegExp($sString, "^.") bei    157286400 Zeichen (    150 MB):  169.365 ms
    10/10 Zeitbedarf StringRegExp($sString, "^.") bei    209715200 Zeichen (    200 MB):  237.681 ms


    Oder eine ganz andere Lösung die ich noch nicht sehe.

    Evtl. lässt sich da ja was mit Nim via DllCall zaubern... eg. SpezRegEx.nim ==> SpezRegEx.dll - eine Funktion, um den String zu übergeben, und eine, um das Pattern auzuwerten.


    Eine weitere Alternative wäre, die in GnuWin enthaltene regex2.dll zu nutzen...

    • Offizieller Beitrag

    Evtl. lässt sich da ja was mit Nim via DllCall zaubern... eg. SpezRegEx.nim ==> SpezRegEx.dll - eine Funktion, um den String zu übergeben, und eine, um das Pattern auzuwerten.

    Wäre es dann nicht besser, gleich eine der Nim-JSON Bibliotheken zu nutzen und die gesamte Verarbeitung in einer Dll ausführen zu lassen?

  • Wäre es dann nicht besser, gleich eine der Nim-JSON Bibliotheken zu nutzen und die gesamte Verarbeitung in einer Dll ausführen zu lassen?

    Ja, das wäre womöglich die beste/schnellste Lösung... ich bin dafür allerdings nicht fit genug und hätte mom. eh nicht die nötige Zeit.

  • Das ging flott.

    ... und zudem auch freundlich :

    Zitat von jpm

    Fix sent to Jon. Many thanks

    Da habe ich in der Vergangenheit schon andere Reaktionen auf (zum Teil berechtigte) Tickets erlebt ;).

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Opt("mustdeclarevars", 1)


    Bringt bei verschachtelten Json Objecten in _Json_Parse() einen Fehler . "Must Declare Variable"...


    Abhilfe schafft in Zeile 251 ein Local vor $o_Value


    Vorher:

    Do

    $o_Value = _JSON_Parse($s_String, $bUseMaps, $i_OsC)

    If @error Then Return SetError(3, $i_OsC, "")


    Nacher:

    Do

    Local $o_Value = _JSON_Parse($s_String, $bUseMaps, $i_OsC)

    If @error Then Return SetError(3, $i_OsC, "")

  • Das würde die Meldung von Opt("MustDeclareVars", 1) in einem Skript, welches die JSON-UDF einbindet, verhindern. Es ist aber kein guter Programmierstil, Global/Local innerhalb von Schleifen zu deklarieren. Wenn, dann sollte man es besser so machen :

    AutoIt
    [...]
    Local $o_Value
    Do
       $o_Value = _JSON_Parse($s_String, $bUseMaps, $i_OsC)
       [...]
    Until ... 

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Und was ist mit Dim[, Const, Static]? 8o

    Dim :

    Dim gilt es in der Tat zu vermeiden (so steht es auch in der Hilfe zu Dim ) :

    "Man sollte Local oder Global anstelle von Dim verwenden, um explizit den Gültigkeitsbereich für die Variable / Konstante / Array festzulegen."

    In der aktuellen Version der JSON-UDF konnte ich keine Deklarationen mittels Dim finden, nur einige Redim's von Arrays .


    Const, Static :

    Zumindest nach den Best_coding_practices keine offiziellen Straftaten :P .


    Ich erhebe allerdings keinerlei Anspruch darauf, die letzte Instanz in Fragen guter Programmierung zu sein ;) . Man denke nur an den Expertenstreit beim Thema bedingter (ternärer) Operator

    86598-musashi-c64-png

    "Am Anfang wurde das Universum erschaffen. Das machte viele Leute sehr wütend und wurde allenthalben als Schritt in die falsche Richtung angesehen."

  • Dim gilt es in der Tat zu vermeiden (so steht es auch in der Hilfe zu Dim ) :

    Ja... ist in meinen Augen aber völliger Quatsch.

    "Man sollte Local oder Global anstelle von Dim verwenden, um explizit den Gültigkeitsbereich für die Variable / Konstante / Array festzulegen."

    Ja... wenn ich den Gültigkeitsbereich explizit festlegen will... doch wenn ich es nicht will, kommt Dim ins Spiel... denn gibt es die Variable bereits im globalen Scope, wird dieser verwendet, anderfalls wird eine lokale Variable erzeugt - und somit hat Dim sehr wohl eine Lebensberechtigung!