![]() |
1
388
这取决于所使用的语言。你写了“语言不可知论”,所以我举几个例子。 在Java、C和Python中,递归与迭代(通常)相比是相当昂贵的,因为它需要分配一个新的堆栈框架。在某些C编译器中,可以使用编译器标志来消除这种开销,这种开销将某些类型的递归(实际上是某些类型的尾部调用)转换为跳转,而不是函数调用。 有时 需要一些相对繁重的操作,特别是在支持多线程执行的实现上。在其中一些环境中,由于mutator和垃圾收集器之间的交互作用(如果两者可能同时运行的话),所以变异是昂贵的。 我知道在一些Scheme实现中,递归通常比循环快。 可以 快点。如果您使用的是命令式语言,那么迭代就是 可能 更快。在某些环境中,这两种方法都会生成相同的程序集(将其放入管道并冒烟)。 在某些环境中,最好的选择不是递归或迭代,而是高阶函数。这些包括“map”、“filter”和“reduce”(也称为“fold”)。这些函数不仅是首选的样式,而且通常更干净,而且在某些环境中,这些函数是第一个(或唯一一个)从自动并行化中得到提升的函数,因此它们可以比迭代或递归快得多。数据并行Haskell就是这种环境的一个例子。 列表理解是另一种选择,但它们通常只是迭代、递归或更高阶函数的语法糖。 |
![]() |
2
61
迭代总是比递归快(在冯·诺依曼建筑中) 如果你从零开始构建一个通用计算机的最小操作,“迭代”首先作为一个构建块出现,并且比“递归”占用更少的资源,因此ergo更快。 从头开始构建伪计算机:扪心自问 :您需要做什么 计算 一个值,即遵循一个算法并得到一个结果? 我们将建立一个概念层次,从零开始,首先定义基本的、核心的概念,然后用这些概念建立第二层次的概念,以此类推。
递归 在冯·诺依曼的建筑里,显然 “迭代” “递归” . 我们有一种 “迭代” 位于概念层次结构的14级。 迭代 在机器代码中总是更快,因为它意味着更少的指令,因此更少的CPU周期。
建议 最后,请注意,您有很多机会使用递归。你有 递归数据结构 现在,你到处都在看一个:支持你所读内容的部分DOM是一个RDS,JSON表达式是一个RDS,你计算机中的分层文件系统是一个RDS,即:你有一个根目录,包含文件和目录,每个目录都包含文件和目录,每一个包含文件和目录的目录。。。 |
![]() |
3
37
因此,正确的方法是首先以最自然的方式编写它,只有在概要分析显示它是关键的情况下才进行优化,然后度量假定的改进。 |
![]() |
4
12
Tail recursion 就像循环一样快。许多函数语言都实现了尾部递归。 |
![]() |
5
12
考虑一下每次迭代和递归都必须做些什么。
你看这里没有多大的分歧余地。 (我假设递归是一个尾部调用,编译器知道这种优化)。 |
![]() |
6
9
这里的大多数答案都忘记了一个明显的罪魁祸首:为什么递归常常比迭代解慢。它与堆栈帧的建立和分解有关,但并不完全是这样。对于每个递归,自动变量的存储通常有很大的不同。在带有循环的迭代算法中,变量通常保存在寄存器中,即使它们溢出,它们也将驻留在1级缓存中。在递归算法中,变量的所有中间状态都存储在堆栈中,这意味着它们将产生更多溢出到内存中。这意味着即使它进行相同数量的操作,它在热循环中也会有大量的内存访问,更糟糕的是,这些内存操作的重用率很低,使得缓存的效率降低。 热释光;DR递归算法通常比迭代算法具有更差的缓存行为。 |
![]() |
7
8
错误的 . 正确答案是 . 例如,这里有两个遍历树的C函数。首先是递归的:
理解代码的细节并不重要。就这样
递归函数比迭代函数运行得快得多。原因是在后者中,对于每个项目
在前者中,只有递归的
另外,访问callstack上的变量速度非常快。这意味着您正在从内存中读取数据,而内存可能总是位于最内部的缓存中。另一方面,显式堆栈必须有
通过仔细的优化,比如内联
但是这个讨论主要是没有意义的,因为递归树遍历是 . 如果你有一个足够大的树,你将用完callstack空间,这就是为什么必须使用迭代算法。 |
![]() |
8
4
一般来说,不,递归不会比在两种形式中都有可行实现的任何实际用法中的循环快。我的意思是,当然,你可以编写一个循环,这需要很长时间,但是有更好的方法来实现同一个循环,它可以比任何通过递归实现同一个问题的方法都要好。
不过,请注意,我说过“两种形式都有可行的实现”。对于像许多排序算法这样的事情,往往没有一种非常可行的实现方法,无法有效地设置自己版本的堆栈,因为子“任务”是流程的固有部分。因此,递归可能与尝试通过循环实现算法一样快。 |
![]() |
9
2
真的,真的 |
![]() |
10
1
函数式编程更多的是关于 什么 “而不是” ". 语言实现者将找到一种优化代码底层工作方式的方法,如果我们不尝试使其比需要的更优化的话。递归也可以在支持尾部调用优化的语言中进行优化。 从程序员的角度来看,更重要的是可读性和可维护性,而不是优化。再次强调,“过早优化是万恶之源”。 |
![]() |
11
0
这只是猜测。一般来说,递归在规模相当的问题上可能不会经常或曾经击败循环,如果两者都使用非常好的算法(不算实现难度),如果与w语言一起使用,则可能会有所不同/ tail call recursion |
|
12
0
理论上是一样的。 数的幂的例子可以用O(ln(n))迭代编码:
|
![]() |
BlurKid · R中for循环时结果的奇怪差异 6 月前 |
![]() |
bigjdawg43 · 迭代多个数据帧中的列并有条件地执行操作 11 月前 |
![]() |
xhamsterIT · 循环VBA Microsoft Excel 11 月前 |
![]() |
Nico44044 · 使用for循环遍历Django模型字段 11 月前 |
![]() |
chanbo chung · 如何在聚合中获得所有可能的组合 11 月前 |
|
Himanshu · 无法在逐行二进制搜索中迭代2D数组中的所有行 11 月前 |
|
stephr · 循环为多个变量选择最接近另一个日期的日期 1 年前 |