2016-02-13 5 views
3

Короткий вопрос: у меня есть javascript, который очень глубоко рекурсивно. Как увеличить размер стека, чтобы я мог его выполнить (что-то вроде «ulimit -s unlimited» в Unix-системах)?Увеличение размера стека в браузерах

Длинная история: мне нужно нарисовать график, и я использую Cytoscape JS (http://js.cytoscape.org/) в сочетании с расширением макета Dagre (https://github.com/cytoscape/cytoscape.js-dagre). Алгоритм рисования идет глубоко в рекурсии, и я в конечном итоге получаю «Недостаток RangeError: максимальный размер стека вызовов превышен» в Chrome и «слишком много рекурсии» в Firefox. Как установить размер стека неограниченным или очень большим (например, «unimit-unimit» в Unix-системах), чтобы рисовать график?

Спасибо!

+0

Вы уверены, что ваш алгоритм является правильным? Вы подсчитали количество вложенных вызовов, которые у вас были в момент выхода из пространства стека? Это разумная цифра? – trincot

+0

Да, алгоритм правильный. Дело в том, что граф довольно большой, а алгоритм рисования глубоко рекурсивно. Однако, используя другие алгоритмы рисования (которые не используют рекурсию), я могу сделать это довольно быстро ... Поэтому я предполагаю, что, если я могу увеличить размер стека до достаточно большого размера, я смогу его нарисовать , Я искал, но не смог найти ответа ... В худшем случае мне нужно будет изменить алгоритм Дагра, чтобы изменить его с рекурсивного на итеративный ... Но я хотел бы проверить, есть ли способ установки стека ограничение размера движка браузеров javascript. – iwicopd2

+1

Добавляем больше контекста, здесь вы можете найти ограничение размера стека для нескольких браузеров: http://stackoverflow.com/questions/7826992/browser-javascript-stack-size-limit?rq=1. Мне просто нужно увеличить этот предел. – iwicopd2

ответ

1

Попробуйте изменить свой алгоритм, чтобы не использовать столько пространства стека на каждой итерации функции. Например:

  • Установка локальных переменных в значение null, когда они не используются.
  • Используйте глобальные переменные для временных расчетов, когда это возможно. Таким образом, эта временная переменная не будет находиться в стеке.
  • Используйте меньше переменных в своей рекурсивной функции. Повторно используйте одни и те же переменные для разных вещей в разных частях функции.
  • Перерыв вашей рекурсивной функции в несколько функций. Некоторые из этих функций не будут рекурсивными, и поэтому локальные переменные в этих функциях не будут выполняться, когда сама рекурсивная функция вызывает себя.
  • Создайте глобальный массив вещей, которые нужно сделать и добавьте элементы в этот список, вместо того, чтобы вызывать функцию рекурсивно. используйте методы push и pop для объекта array().
  • У вас меньше параметров для вашей рекурсивной функции. Передайте объект вместо этого.

Надеюсь, эти идеи помогут вам.

+0

Здравствуйте. Спасибо за ответ. Я подумал о некоторых из этих вещей, но ваш список действительно более совершенен!Однако, что, если я сделал все возможное, чтобы минимизировать пространство стека при каждом вызове функции, но сам алгоритм слишком сильно рекурсивно, и я не могу изменить итеративный алгоритм? То есть Мне действительно нужно увеличить размер стека? Я просто не могу сделать это в современных браузерах? Должен ли я таким образом перекопировать мой сценарий в качестве настольного приложения, чтобы иметь большой размер стека? – iwicopd2

+0

Я программировал один раз в C в Windows и имел очень большое двоичное дерево. Я написал рекурсивную функцию для удаления дерева после завершения функции. Рекурсивная функция сработает. Мне пришлось переписать рекурсивную функцию на итеративную функцию. Я не думаю, что изменение языков или расширение стека исправят проблему с вашим алгоритмом. Если вы удвоите размер стека или утроите размер стека, у вас, вероятно, все еще будет такая же проблема. –

+0

Привет. Я использую стороннюю библиотеку, и несколько функций углубляются в рекурсию. Для меня нецелесообразно изменять всю библиотеку. Я также соглашаюсь и предпочитаю писать код итеративно, чем рекурсивно, но иногда рекурсия просто более чиста алгоритмически. В UNIX-системах иногда у нас есть это, и ulimit -s unlimited решает проблему. У меня есть обходное решение для js, которое связано с изменением размера стека Google Chrome, вызвав его аргументами командной строки -js-flags = "- stack_size x" с большим x. Огромное спасибо за помощь. – iwicopd2