Python: Каков жесткий предел рекурсии для Linux, Mac и Windows?
Питона sys
модуль обеспечивает функцию setrecursionlimit
это позволяет вам изменить максимальный предел рекурсии Python. Документы говорят:
Максимально возможный предел зависит от платформы.
Мой вопрос: каковы максимально возможные ограничения для различных платформ под CPython? Я хотел бы знать значения для Linux, Mac и Windows.
ОБНОВЛЕНИЕ: мы можем избежать ответов "Вы делаете это неправильно"? Я знаю, что попытка сделать очень глубокую рекурсию, как правило, плохая идея. Я рассмотрел плюсы и минусы в своей конкретной ситуации и решил, что хочу это сделать.
3 ответа
В Windows (по крайней мере) sys.setrecursionlimit
не полная история Жесткий лимит на основе потока, и вам нужно позвонить threading.stack_size
и создать новую тему, как только вы достигнете определенного предела. (Я думаю, что 1 МБ, но не уверен) Я использовал этот подход, чтобы увеличить его до стека 64 МБ.
import sys
import threading
threading.stack_size(67108864) # 64MB stack
sys.setrecursionlimit(2 ** 20) # something real big
# you actually hit the 64MB limit first
# going by other answers, could just use 2**32-1
# only new threads get the redefined stack size
thread = threading.Thread(target=main)
thread.start()
Я не пытался увидеть, какие ограничения могут быть на threading.stack_size
, но не стесняйтесь попробовать... вот где вам нужно искать.
В итоге, sys.setrecursionlimit
это просто предел, установленный самим переводчиком. threading.stack_size
позволяет манипулировать фактическим лимитом, налагаемым ОС. Если вы превысите последний предел первым, Python просто полностью рухнет.
Значения по умолчанию для основных операционных систем;
- Для Windows: 2000
- Для Linux: 1000
- Для Mac OS: 1000
Вы не должны злоупотреблять рекурсивными вызовами в CPython. Он не имеет хвостовой оптимизации, вызовы функций занимают много памяти и времени обработки. Эти ограничения могут не относиться к другим реализациям, это не входит в чертежи.
В CPython рекурсия хороша для обхода структур данных (где ограничение 1000 должно быть достаточно для всех), но не для алгоритмов. Если бы я должен был реализовать, скажем, алгоритмы, связанные с графами, и достичь предела рекурсии, я бы либо реализовал свой собственный стек и использовал итерации, либо искал библиотеки, реализованные на C/C++/ что угодно, прежде чем поднимать предел вручную.