【问题标题】:Are there any cases when I would want to use an explicit stack over recursion?是否有任何情况下我想使用显式堆栈而不是递归?
【发布时间】:2010-12-06 23:10:28
【问题描述】:

在任何情况下,我想在算法中使用显式堆栈数据结构,而不是进行递归(使用调用堆栈)?

以一种方式进行比另一种方式有什么好处吗?我认为使用显式数据结构会更高效,因为它不需要方法调用,但又是微优化领域。

【问题讨论】:

    标签: language-agnostic recursion stack


    【解决方案1】:

    我能想到的一种情况是你可以支持显式堆栈:

    您可能在一个系统上,进入和/或退出堆栈帧的成本很高,并且您的递归深度非常深。想象一下树中的深度优先。

    在这样的设置中,如果您发现请求的树节点有 100 层深,如果您使用递归,则需要一一销毁 100 个堆栈帧。

    使用显式堆栈,您可以从函数中返回,整个堆栈将立即释放。

    【讨论】:

      【解决方案2】:

      使用显式结构可以让您以更简单的代码换取更高的性能。

      使用堆栈进行递归通常允许非常优雅和简短的代码。

      使用显式堆栈通常会使代码(很多)更复杂,但您可以保存在几个地方:

      • 您无需为函数/方法调用付费(对于脚本/动态语言非常有用)
      • 您只能保存您需要的那些位。如果使用递归,则必须保存整个堆栈帧(包括所有局部变量、返回地址、所有参数)。
      • 您可以在显式堆栈中环顾四周(即您可以看到“之前的两次递归”发生了什么),这对于普通堆栈来说有点困难
      • 虽然实际堆栈可能由于多种原因受到限制,但您可以根据需要为隐式堆栈分配尽可能多的内存(甚至使用数据库)。

      【讨论】:

        【解决方案3】:

        调用堆栈比内存中的结构更受限制,具体取决于您的运行时。 很多时候,由于 .NET 中的 StackOverflowExceptions,我不得不递归到堆栈数据结构中。

        【讨论】:

          【解决方案4】:

          递归调用堆栈通常是有限的,而显式堆栈对于大多数实际用途来说是无限的。因此,如果您期望具有非常深的递归级别(取决于您的平台),最好重新设计显式堆栈的算法。例如。许多基于图或树的算法有两种形式:递归和显式堆栈。

          【讨论】:

            【解决方案5】:

            显式堆栈还可以为您提供更好的引用局部性,从而提高缓存效率。在实际数据之间的堆栈中存储函数地址的多个副本是缓存污染。

            【讨论】:

              猜你喜欢
              • 2021-04-08
              • 2014-09-03
              • 2016-11-01
              • 1970-01-01
              • 1970-01-01
              • 2016-01-03
              • 1970-01-01
              • 2018-03-09
              • 1970-01-01
              相关资源
              最近更新 更多