我知道递归有时比循环干净得多,而且我没有问什么时候应该使用递归而不是迭代,我知道已经有很多问题了。
我要问的是,递归 比 循环快吗?在我看来,你总是能够改进循环并让它比递归函数更快地执行,因为循环不存在不断设置新的堆栈帧。
我专门寻找递归是否在递归是处理数据的正确方法的应用程序中更快,例如在某些排序函数、二叉树等中。
这取决于所使用的语言。你写了“语言不可知论”,所以我会举一些例子。
在 Java、C 和 Python 中,与迭代(通常)相比,递归相当昂贵,因为它需要分配新的堆栈帧。在某些 C 编译器中,可以使用编译器标志来消除这种开销,它将某些类型的递归(实际上是某些类型的尾调用)转换为跳转而不是函数调用。
在函数式编程语言实现中,有时迭代可能非常昂贵,而递归可能非常便宜。在许多情况下,递归被转换为简单的跳转,但是更改循环变量(它是可变的) 有时 需要一些相对繁重的操作,尤其是在支持多线程执行的实现上。由于mutator和垃圾收集器之间的交互,如果两者可能同时运行,突变在其中一些环境中是昂贵的。
我知道在某些 Scheme 实现中,递归通常比循环更快。
简而言之,答案取决于代码和实现。使用你喜欢的任何风格。如果您使用的是函数式语言,递归 可能 会更快。如果您使用的是命令式语言,迭代 可能会 更快。在某些环境中,这两种方法都会生成相同的程序集(将其放入您的管道并抽它)。
附录: 在某些环境中,最好的选择既不是递归也不是迭代,而是高阶函数。这些包括“map”、“filter”和“reduce”(也称为“fold”)。这些不仅是首选样式,而且它们通常更简洁,而且在某些环境中,这些函数是第一个(或唯一一个)从自动并行化中获得提升的函数——它们可以比迭代或递归快得多。Data Parallel Haskell 就是这种环境的一个例子。
列表推导是另一种选择,但它们通常只是迭代、递归或高阶函数的语法糖。