Pegjs: [question] Conseils sur {cache: true} et gestion des cas raisonnables de manque de mémoire

Créé le 22 nov. 2018  ·  3Commentaires  ·  Source: pegjs/pegjs

Type de probleme

  • Question : oui

Conditions préalables

  • Pouvez-vous reproduire le problème ? : oui
  • Avez-vous recherché les problèmes du référentiel ? : Oui, regardé cache dans les problèmes GitHub, trouvé quelques problèmes sur le cache mais pas ce que je demande.
  • Avez-vous consulté les forums ? : oui, essayé googlegroups/cache , aucun résultat associé
  • Avez-vous effectué une recherche sur le Web (google, yahoo, etc.) ? : oui

La description

J'analyse un texte assez lourd (500 Ko) fourni par l'utilisateur en utilisant une grammaire d'environ 1 000 lignes.

  • Lors du passage de {cache: true} ...

    • ... et en disant à Node d'utiliser 3 Go de tas (avec --max-old-space-size=3000 ), le tas passe à 2,5 Go et l'analyse réussit en 12 secondes.

    • ... et en laissant le nœud 10 par défaut à 800 Mo de tas, l'analyse se bloque avec un MOO.

  • Lors du passage de {cache: false} , comme prévu, l'analyse des horloges est légèrement plus rapide à 10 s (cas non pathologique) et n'augmente pas l'utilisation de la mémoire.

Il s'agit de données utilisateur et les ressources de mon serveur sont limitées, donc remplacer Node pour utiliser X Go de tas n'est pas une option, car demain je pourrais obtenir 1 Mo de données utilisateur qui nécessiteraient X + 1 Go de tas. Et bien sûr, j'aimerais continuer à utiliser {cache: true} lorsque cela est possible, pour "éviter le temps d'analyse exponentiel dans les cas pathologiques" , que j'ai rencontrés.

Quelle approche recommandez-vous?

  • Y a-t-il quelque chose de intégré dans PEG.js pour renflouer lorsque l'utilisation de la mémoire devient critique ?
  • Mes tentatives pour gérer cela avec des délais d'attente ne sont pas excellentes, car l'utilisation de la mémoire peut augmenter plus rapidement que le délai d'attente.
  • Pour autant que je sache, il est impossible d'intercepter un Node OOM.
  • Enfin, j'envisage de changer l'utilisation de {cache: true} fonction de la taille de l'entrée. Cela me coûtera plus d'utilisation du processeur, mais au moins je ne ferai pas de MOO.
  • D'autres idées ?

Merci pour PEG.js ! ??

Logiciel

  • PEG.js : 0.10.0
  • Node.js : 10.13.0
  • NPM ou fil : npm 6.4.1
  • Navigateur : N/A
  • Système d'exploitation : AWS Linux
performance question

Tous les 3 commentaires

Les temps d'analyse exponentielle sont quelque chose qui se produit dans des cas très pathologiques, et je recommanderais d'y réécrire la grammaire.
Considérez https://github.com/sirthias/pegdown/issues/43#issuecomment -18469752
(je ne suis pas contributeur)

Comme @polkovnikov-ph l'a souligné, il est préférable de réécrire les parties de votre grammaire qui traitent des cas pathologiques, mais si vous continuez à frapper des cas OOM, il serait peut-être préférable de faire ce que vous avez suggéré (@ronjouch) ; basculer l'option _cache_ en fonction de la taille de l'entrée : cache: input.length >= 250000

Après cela (et seulement si vous avez accès au texte fourni par l'utilisateur), je suggérerais d'examiner toute entrée qui atteint les cas OOM pour localiser les cas pathologiques courants et mettre à jour votre grammaire pour les gérer explicitement afin que vous puissiez réduire le nombre de cas OOM frapper votre application.

Si vous rencontrez encore souvent des cas de MOO et que vous souhaitez non seulement réécrire votre grammaire, mais également ajouter une passe supplémentaire (ou quelques-unes) à votre chaîne d'outils, je vous suggère d'essayer l'une de ces méthodes :

  • diviser une grande entrée et mettre à jour votre grammaire pour gérer des parties partielles de la syntaxe que vous analysez, puis lorsque toutes les entrées sont analysées, joignez tout (cela n'est probablement viable que si votre analyseur généré renvoie AST, pas sûr du contraire)
  • utiliser une expression régulière pour identifier la syntaxe dans le texte fourni par l'utilisateur qui pourrait conduire à des cas pathologiques avant de l'envoyer à l'un des 2 analyseurs générés : un analyseur normal et un autre pour gérer les cas pathologiques
  • vous pouvez toujours utiliser la grammaire PEG.js pour générer un analyseur qui se comporte comme des tokenizers et crée un analyseur capable d'analyser de manière optimale à la fois les entrées normales et les entrées contenant une syntaxe pouvant conduire à des cas pathologiques (vous demandera d'investir plus de temps dans l'apprentissage des analyseurs, et va à l'encontre du but d'un générateur d'analyseur, mais _est presque toujours une option viable si vous savez ce que vous faites_)

@polkovnikov-ph @futagoza merci à vous deux d'avoir pris le temps de revenir avec des conseils 👍 ! Ça a du sens. J'ai déployé la solution de contournement de taille et envisagerai de réécrire la grammaire la prochaine fois que des problèmes frapperont à la porte. Bonne journée; clôture de la question.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

dmajda picture dmajda  ·  15Commentaires

richb-hanover picture richb-hanover  ·  7Commentaires

doersino picture doersino  ·  15Commentaires

mattkanwisher picture mattkanwisher  ·  5Commentaires

emmenko picture emmenko  ·  15Commentaires