【问题标题】:How does pypy handle recursions?pypy如何处理递归?
【发布时间】:2011-09-24 18:19:05
【问题描述】:

我有一个用 python 编写的脚本,它运行良好,但我很想知道是否可以加快它的速度。它基本上是递归脚本。

如果我在普通的 python 2.7 中运行它,大约需要 30 秒。当我使用 pypy 运行相同的东西时,会出现以下错误:

RuntimeError: maximum recursion depth exceeded

我不确定 pypy 有什么不同,因为我没有修改脚本。

谁能帮我理解发生了什么?

更新: 好的,我想通了。增加限制有帮助,但我认为我运行了错误的文件。我在 bin 目录下找到了一个名为 py.py 的文件,并且正在使用它。我不确定该文件的作用,但它比普通的 python 慢。我不得不搜索并发现“pypy-c”现在似乎可以工作了。

【问题讨论】:

  • 如果没有看到代码,就很难诊断。递归限制是特定于实现的限制,PyPy 可能比 CPython 的限制更小?您期望多少级递归?
  • 查看源代码可能会有所帮助。如果它足够短,或者可以在保留此行为的同时做到这一点(适用于 CPython,PyPy 上的递归错误),那么提交 PyPy 错误报告也可能是值得的,因为与 CPython 的兼容性是 PyPy 的高优先级。我认为这不太可能属于少数预期/公认的不兼容之一。
  • @NedBatchelder:好主意,同意。尽管pypy.readthedocs.org/en/latest/… 建议 PyPy 的递归限制高于 CPython 的默认值(我认为允许的确切深度应取决于调用帧的大小,因此如果您使用的变量比平均函数多得多,则限制可能会更低)。
  • 谢谢你,Deinan 和 Ned。我更新了我的代码,但尽管遵循了 DSM 的建议,但仍然遇到同样的问题)。我认为我做的唯一不同的是我从源代码编译(因为我的发行版不存在二进制文件)。当我在我的 linux 发行版上启动它而不是在我的 mac(通过二进制文件安装)上运行它时,我确实收到了一些奇怪的 c 消息,但是 pypy 的演示文件在两种安装下都可以工作,所以我不确定这是否是一个问题。
  • 啊,更新清除了一切。您在 CPython 下运行解释的 PyPy,这自然要慢得多,并且通过解释器和您的代码调用推动了 CPython 的 1000 次调用限制。 pypy-c 是打算使用的本机编译解释器,它处理递归的方式与预期一样。

标签: python pypy


【解决方案1】:

正如您在更新中建议的那样,您的问题是您使用的是 py.py(用于在 CPython 之上运行 PyPy 的解释器)。 PyPy 通常比 CPython 具有更高的递归限制。您可以使用sys.setrecursionlimit() 来增加递归限制,sys.getrecursionlimit() 不提供实际的递归限制。

PyPy 1.6.0:

>>>> sys.getrecursionlimit()
100

>>>> def infinite(level=0):
....     print level
....     return infinite(level+1)
.... 

>>> infinite()
<snip>
1010
Traceback (most recent call last):
  File "<console>", line 2, in infinite
RuntimeError: maximum recursion depth exceeded

>>> sys.setrecursionlimit(sys.maxint)

>>> infinite()
<snip>
9769
zsh: segmentation fault  pypy

【讨论】:

    猜你喜欢
    • 2014-05-23
    • 2014-09-26
    • 2012-05-02
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 2015-05-20
    • 2014-09-13
    相关资源
    最近更新 更多