Iterative vs. Recursive Approaches

Eyal Lantzman, 5 Nov 2007 CPOL
 
     
 
 

Introduction

This article was originally posted at blogs.microsoft.co.il/blogs/Eyal.

Recursive function – is a function that is partially defined by itself and consists of some simple case with a known answer. Example: Fibonacci number sequence, factorial function, quick sort and more.
Some of the algorithms/functions can be represented in an iterative way and some may not.

Iterative
functions – are loop based imperative repetitions of a process (in
contrast to recursion which has a more declarative approach).

Comparison between Iterative and Recursive Approaches from Performance Considerations

Factorial

Collapse | Copy Code
//recursive function calculates n!
static int FactorialRecursive(int n)
{
if (n <= 1) return 1;
return n * FactorialRecursive(n - 1);
} //iterative function calculates n!
static int FactorialIterative(int n)
{
int sum = 1;
if (n <= 1) return sum;
while (n > 1)
{
sum *= n;
n--;
}
return sum;
}
N Recursive Iterative
10 334 ticks 11 ticks
100 846 ticks 23 ticks
1000 3368 ticks 110 ticks
10000 9990 ticks 975 ticks
100000 stack overflow 9767 ticks

As we can clearly see, the recursive is a lot slower than the iterative (considerably) and limiting (stackoverflow).

The reason for the poor performance is heavy push-pop of the registers in the ill level of each recursive call.

Fibonacci

Collapse | Copy Code
//--------------- iterative version ---------------------
static int FibonacciIterative(int n)
{
if (n == 0) return 0;
if (n == 1) return 1; int prevPrev = 0;
int prev = 1;
int result = 0; for (int i = 2; i <= n; i++)
{
result = prev + prevPrev;
prevPrev = prev;
prev = result;
}
return result;
} //--------------- naive recursive version ---------------------
static int FibonacciRecursive(int n)
{
if (n == 0) return 0;
if (n == 1) return 1; return FibonacciRecursive(n - 1) + FibonacciRecursive(n - 2);
} //--------------- optimized recursive version ---------------------
static Dictionary<int> resultHistory = new Dictionary<int>(); static int FibonacciRecursiveOpt(int n)
{
if (n == 0) return 0;
if (n == 1) return 1;
if (resultHistory.ContainsKey(n))
return resultHistory[n]; int result = FibonacciRecursiveOpt(n - 1) + FibonacciRecursiveOpt(n - 2);
resultHistory[n] = result; return result;
}
N Recursive Recursive opt. Iterative
5 5 ticks 22 ticks 9 ticks
10 36 ticks 49 ticks 10 ticks
20 2315 ticks 61 ticks 10 ticks
30 180254 ticks 65 ticks 10 ticks
100 too long/stack overflow 158 ticks 11 ticks
1000 too long/stack overflow 1470 ticks 27 ticks
10000 too long/stack overflow 13873 ticks 190 ticks
100000 too long/stack overflow too long/stack overflow 3952 ticks

As before, the recursive approach is worse than iterative however, we could apply memorizationpattern (saving previous results in dictionary for quick key based access), although this pattern isn't a match for the iterative approach (but definitely an improvement over the simple recursion).

Notes

  1. The calculations may be wrong in big numbers, however the algorithms should be correct.
  2. For timer calculations, I used System.Diagnostics.Stopwatch.

Points of Interest

  1. Try not to use recursion in system critical locations.
  2. Elegant solutions not always the best performing when used in "recursive situations".
  3. If you required to use recursion, at least try to optimize it with dynamic programming approaches (such as memorization).

转自:http://www.codeproject.com/Articles/21194/Iterative-vs-Recursive-Approaches

关于Tail Recursive

It is possible that recursion will be more expensive, depending on if the recursive function is tail recursive (last line is recursive call). Tail recursion should be recognized by the compiler and optimized to its iterative counterpart (while maintaining the concise, clear implementation you have in your code).

I would write the algorithm in the way that makes the most sense and is the most clear for the poor sucker (be it yourself or someone else) that has to maintain the code in a few months or years. If you run into performance issues, then profile your code, and then and only then look into optimizing by moving over to an iterative implementation. You may want to look into memoization and dynamic programming.

转自: http://stackoverflow.com/questions/72209/recursion-or-iteration

参考资料:

尾调用:

http://zh.wikipedia.org/wiki/%E5%B0%BE%E8%B0%83%E7%94%A8

http://en.wikipedia.org/wiki/Tail_call

【算法】转载:Iterative vs. Recursive Approaches的更多相关文章

  1. A* 寻路算法[转载]

    A* 寻路算法 转载地址:http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html 原文地址: http://www.gamedev ...

  2. ICP算法(Iterative Closest Point迭代最近点算法)

    标签: 图像匹配ICP算法机器视觉 2015-12-01 21:09 2217人阅读 评论(0) 收藏 举报 分类: Computer Vision(27) 版权声明:本文为博主原创文章,未经博主允许 ...

  3. 【转】ICP算法(Iterative Closest Point迭代最近点算法)

    原文网址:https://www.cnblogs.com/sddai/p/6129437.html.转载主要方便随时可以查看,如有版权要求请及时联系. 最近在做点云匹配,需要用c++实现ICP算法,下 ...

  4. GJM : 数据结构 - 轻松看懂机器学习十大常用算法 [转载]

     转载请联系原文作者 需要获得授权,非法转载 原文作者将享受侵权诉讼 文/不会停的蜗牛(简书作者)原文链接:http://www.jianshu.com/p/55a67c12d3e9 通过本篇文章可以 ...

  5. 解读BloomFilter算法(转载)

    1.介绍 BloomFilter(布隆过滤器)是一种可以高效地判断元素是否在某个集合中的算法. 在很多日常场景中,都大量存在着布隆过滤器的应用.例如:检查单词是否拼写正确.网络爬虫的URL去重.黑名单 ...

  6. 数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++

    数据结构图之三(最短路径--迪杰斯特拉算法)   [1]最短路径 最短路径?别乱想哈,其实就是字面意思,一个带边值的图中从某一个顶点到另外一个顶点的最短路径. 官方定义:对于内网图而言,最短路径是指两 ...

  7. AStar算法(转载)

    以下的文章来至http://blog.csdn.net/debugconsole/article/details/8165530,感激这位博主的翻译,可惜图片被和谐了,所以为方便阅读,我重新把图片贴上 ...

  8. 浅谈MySQL索引背后的数据结构及算法(转载)

    转自:http://blogread.cn/it/article/4088?f=wb1 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储 ...

  9. 展开BOM并使用最终用量的算法(转载)

    本文系转载子ITPUB,如果有侵犯您权益的地方,烦请及时的告知与我,我即刻将停止侵权行为: 网址:http://www.itpub.net/thread-1020586-1-1.html http:/ ...

随机推荐

  1. js setInterval() 用法示例

      Created by Marydon on 1.定义 语法:setInterval(param1,param2) param1 要调用的函数或要执行的代码串. param2 周期性调用param1 ...

  2. java线上应用问题排查方法和工具

    linux性能监测点 CPU, Memory, IO, Network Linux性能监测工具-cpu 基本概念: 上下文切换(Context Switches): 如果可运行的线程数大于CPU的数量 ...

  3. IDEA创建maven项目jar更新缓慢问题

    转自:http://www.cnblogs.com/ae6623/p/4416256.html 国内连接maven官方的仓库更新依赖库,网速一般很慢,收集一些国内快速的maven仓库镜像以备用. 最新 ...

  4. 【LeetCode】80. Remove Duplicates from Sorted Array II (2 solutions)

    Remove Duplicates from Sorted Array II Follow up for "Remove Duplicates":What if duplicate ...

  5. Tomcat JNDI + spring配置

    http://hi.baidu.com/lzpsky/item/f9a727ba823257eb4ec7fd27 一.简介 JNDI : Java Naming and Directory Inter ...

  6. 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]

    在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...

  7. Kafka中Topic级别配置

    一.Kafka中topic级别配置 1.Topic级别配置 配置topic级别参数时,相同(参数)属性topic级别会覆盖全局的,否则默认为全局配置属性值. 创建topic参数可以设置一个或多个--c ...

  8. 转:造HTTP请求Header实现“伪造来源IP”

    构造 HTTP请求 Header 实现“伪造来源 IP ” 在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以 ...

  9. Openresty增加waf配置

    Openresty增加waf配置 1. Ngx lua waf 说明 防止sql注入,本地包含,部分溢出,fuzzing测试,xss,SSRF等web攻击 防止svn/备份之类文件泄漏 防止Apach ...

  10. yield与send实现协程操作

    yield与send实现协程操作 之前我们说过,在函数内部含有yield语句即称为生成器. 下面,我们来看看在函数内部含有yield语句达到的效果.首先,我们来看看以下代码: def foo(): w ...