2017-06-24 2 views
2

J'ai un algorithme, qui fonctionne de façon récursive relativement profonde, de sorte qu'une taille maximale de pile dépassée par l'exception survienne finalement (sans être une récursivité sans fin!).Comment savoir quand la pile Javascript est pleine?

Mon algorithme peut se décomposer lui-même, pour procéder de manière asynchrone en utilisant dès que possible, mais cela ralentit chaque fois l'exécution massivement. Je voudrais avoir un moyen (rapide) de connaître le pourcentage d'utilisation de la pile, donc mon algorithme peut décider de continuer de façon synchrone s'il est inférieur à 90%, mais continuer de façon asynchrone quand il est supérieur. Je sais que cette valeur doit être interne, mais existe-t-il un moyen d'y accéder? D'un autre côté, je pourrais imaginer d'attraper la taille maximale de la pile dépassée erreur, mais je read here, que ce n'est pas possible (pourquoi pas? Lancer cette exception reviendrait à retourner à l'appelant, ce qui devrait effectivement réduire la taille de la pile et les anciennes entrées de pile devraient toujours être intactes pour cela ???)

Bien sûr, une façon serait de passer une variable de compteur à travers toutes mes fonctions, mais c'est gênant. Aussi, il n'est pas clair, à quelle valeur de comptage ma pile est à 90%, parce que je ne sais pas, quelle est la taille de la pile et quelle est la taille de chacune de mes images de pile.

Donc en fait, il semble que JavaScript soit né pour échouer dans ce cas même si le programmeur pouvait l'éviter, s'il avait accès à l'information dont il avait besoin - quelque part mais gardé secret pour des raisons inconnues?

+0

S'il vous plaît montrer votre travail. Cela ressemble à un problème avec votre algorithme, pas comment l'interpréteur javascript l'exécute. Qu'est-ce que vous exécutez cela? Noeud ou un navigateur? Qu'est-ce que votre algo essaie même d'accomplir? Nous avons besoin de ces détails. – Soviut

+0

Je ne peux pas fournir "l'algorithme" - il traite les données et s'installe récursivement en fonction des données. Il n'y a pas de problème avec mon algorithme. Lorsque la structure de données est imbriquée suffisamment profondément, ce qui arrive en pratique, la pile va se renverser sans avoir de récursion sans fin. –

+0

Si votre récursivité est si importante qu'elle déborde de la pile, vous devez réécrire votre algo, de même que la récursion de courte durée. – Soviut

Répondre

1

Il est impossible de mesurer l'utilisation actuelle de la pile sans la suivre elle-même, en transmettant une variable ou en faisant éventuellement référence à l'état partagé.

Mais vous pouvez juste attraper l'erreur de débordement d'appel quand il est plein. (La question floue que vous avez liée parlait d'autre chose, I've written a new answer to clarify.) Vous pourriez utiliser ceci pour avoir une idée approximative de la taille de la pile disponible, mais cela n'est probablement pas garanti pour les différentes fonctions en fonction des optimisations et autres.

var maxDepth = 0; 
 
function popTheStack() { 
 
    maxDepth++; 
 
    popTheStack(); 
 
} 
 

 
try { 
 
    popTheStack(); 
 
} catch (ex) { 
 
    console.log("caught " + ex + " at depth " + maxDepth); 
 
}

+1

N'a pas lu cette autre question assez bien.Je vais faire un jsperf, pour voir, combien introduire des blocs catch dans mon algorithme affecte la performance. –

1

Cela dépend des navigateurs. Votre approche n'est pas le meilleur choix pour un problème, bien sûr nous ne pouvons pas annoncer aux utilisateurs comme "votre demande est trop lourde et nous ne pouvons pas la gérer". Une autre approche est l'algorithme de-récursive, toutes les solutions récursives auront toujours un non-récursif correspondant. Vous pouvez simuler une pile par vous-même, plutôt qu'une pile système, et implémenter une boucle pour trouver le résultat.