Pegjs: [Frage] Ratschläge zu {cache: true} und zum Umgang mit vernünftigem Speichermangel

Erstellt am 22. Nov. 2018  ·  3Kommentare  ·  Quelle: pegjs/pegjs

Problemtyp

  • Frage: ja

Voraussetzungen

  • Können Sie das Problem reproduzieren?: ja
  • Haben Sie die Repository-Probleme durchsucht?: Ja, cache in den GitHub-Problemen angesehen, einige Probleme im Cache gefunden, aber nicht das, wonach ich frage.
  • Haben Sie die Foren überprüft?: Ja, Googlegroups / Cache ausprobiert, keine entsprechenden Ergebnisse
  • Haben Sie eine Websuche durchgeführt (Google, Yahoo usw.)?: Ja

Beschreibung

Ich analysiere ein ziemlich umfangreiches (500 KB) Stück vom Benutzer bereitgestellten Texts mit einer ~ 1000-Zeilen-Grammatik.

  • Beim Passieren von {cache: true} ...

    • ... und weist Node an, 3 GB Heap zu verwenden (mit --max-old-space-size=3000 ), der Heap wächst auf 2,5 GB und das Parsing ist in 12 Sekunden erfolgreich.

    • ... und Node 10 standardmäßig auf 800 MB Heap belassen, stürzt das Parsen mit einem OOM ab.

  • Wenn {cache: false} , läuft das Parsing wie erwartet mit 10s etwas schneller (nicht pathologischer Fall) und erhöht die Speicherauslastung nicht.

Dies sind Benutzerdaten und meine Serverressourcen sind begrenzt, daher ist es keine Option, Node zu drängen, um X GB Heap zu verwenden, da ich morgen möglicherweise 1 MB Benutzerdaten bekomme, die X + 1 GB Heap erfordern würden. Und natürlich würde ich gerne weiterhin {cache: true} wenn möglich, um "exponentielle Parsing-Zeiten in pathologischen Fällen zu

Welche Vorgehensweise empfehlen Sie?

  • Ist in PEG.js etwas eingebaut, um zu retten, wenn die Speicherauslastung kritisch wird?
  • Meine Versuche, dies mit Zeitüberschreitungen zu handhaben, sind nicht großartig, da die Speicherauslastung möglicherweise schneller als die Zeitüberschreitung anwächst.
  • Soweit ich weiß, ist es unmöglich, ein Node OOM abzufangen.
  • Schließlich erwäge ich, die Verwendung von {cache: true} basierend auf der Größe der Eingabe zu wechseln. Das kostet mich mehr CPU-Auslastung, aber zumindest werde ich nicht OOM.
  • Andere Ideen?

Danke für PEG.js! 🙂

Software

  • PEG.js: 0.10.0
  • Node.js: 10.13.0
  • NPM oder Garn: npm 6.4.1
  • Browser: N/A
  • Betriebssystem: AWS Linux
performance question

Alle 3 Kommentare

Exponentielle Parsing-Zeiten treten in sehr pathologischen Fällen auf, und ich würde empfehlen, die Grammatik dort neu zu schreiben.
Betrachten Sie https://github.com/sirthias/pegdown/issues/43#issuecomment -18469752
(Ich bin kein Mitwirkender)

Wie @polkovnikov-ph betonte, ist es am besten, Teile Ihrer Grammatik umzuschreiben, die sich mit pathologischen Fällen befassen, aber wenn Sie weiterhin auf OOM-Fälle stoßen, ist es möglicherweise besser, das zu tun, was Sie (@ronjouch) vorgeschlagen haben; schalte die _cache_ Option basierend auf der Größe der Eingabe um: cache: input.length >= 250000

Danach (und nur wenn Sie Zugriff auf den vom Benutzer bereitgestellten Text haben) würde ich vorschlagen, jede Eingabe, die auf OOM-Fälle trifft, zu untersuchen, um gängige pathologische Fälle zu lokalisieren und Ihre Grammatik zu aktualisieren, um diese explizit zu behandeln, damit Sie die Anzahl der OOM-Fälle reduzieren können Ihre App treffen.

Wenn Sie immer noch häufig auf OOM-Fälle stoßen und bereit sind, nicht nur Ihre Grammatik neu zu schreiben, sondern Ihrer Toolchain auch einen zusätzlichen Durchgang (oder wenige) hinzuzufügen, empfehle ich Ihnen, eine dieser Methoden auszuprobieren:

  • Aufteilen großer Eingaben und Aktualisieren Ihrer Grammatik, um partielle Teile der Syntax zu verarbeiten, die Sie parsen. Wenn alle Eingabeteile geparst sind, verbinden Sie alles (dies ist höchstwahrscheinlich nur möglich, wenn Ihr generierter Parser AST zurückgibt, sonst bin ich mir nicht sicher).
  • Verwenden Sie eine Regex, um eine Syntax im vom Benutzer bereitgestellten Text zu identifizieren, die zu pathologischen Fällen führen könnte, bevor Sie sie an einen von 2 generierten Parsern senden: einen normalen Parser und einen anderen, um pathologische Fälle zu behandeln
  • Sie können jederzeit die PEG.js-Grammatik verwenden, um einen Parser zu generieren, der sich wie Tokenizer verhält, und einen Parser erstellt, der sowohl normale Eingaben optimal parsen kann als auch Eingaben, die eine Syntax enthalten, die zu pathologischen Fällen führen kann (dies erfordert mehr Zeit in Lernen über Parser und verfehlt irgendwie den Zweck eines Parser-Generators, aber _ist fast immer eine praktikable Option, wenn Sie wissen, was Sie tun_)

@polkovnikov-ph @futagoza danke euch beiden, dass ihr euch die Zeit genommen habt, mit Ratschlägen zurückzukommen 👍! Das macht Sinn. Ich habe die Problemumgehung für die Größe bereitgestellt und werde erwägen, die Grammatik das nächste Mal neu zu schreiben, wenn Probleme an der Tür klopft. Schönen Tag; die Frage schließen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen