参考

  • 尾调用详解 - 阮一峰
  • go&plan9 - 曹大

什么是尾调用

```func g(n int) {fmt.Println(n)}func f(m int) {m++g(m)}在f()函数内最后直接调用g()
```

尾调用优化

  • 我们把调用函数称作caller,被调用函数称作callee
  • 在程序运行过程中,需要先保存caller现场在栈帧中,然后调用callee。caller栈帧会在callee调用返回后,继续执行完毕,然后释放
  • 但是,在尾调用中,callee在caller的最后,所以caller的栈帧其实在callee调用前就可以释放了,优化的目的也是为此
  • 提前释放释放caller栈帧,可大大减少内存使用,同时避免了调用层级过多导致的栈空间爆炸
  • 对plan9汇编和栈帧概念不熟悉的同学可以参考这篇译文go&plan9

尾递归调用

    ```func f(n int) {fmt.Println(n)n++f(n)}尾递归调用:在f()函数内最后再调用自己在C++等的O2级别优化中,一般会被优化为for循环
```

golang编译器是否会做尾递归优化

  • 从实验结果来看,不会做优化

验证方法一:查看汇编代码

  1. 写一个尾递归函数
  • [外链图片转存中…(img-ZUiRLmHF-1614241682059)]
  1. go tool compile -S demo.go
  • [外链图片转存中…(img-DR4FoyHZ-1614241682061)]

验证方法二:编译运行

  1. 写一个尾递归函数,递归层级搞的足够大
  • [外链图片转存中…(img-U8jMykaF-1614241682062)]
  1. go run demo.go
  • [外链图片转存中…(img-xHzWnOh8-1614241682064)]
  1. 内存爆炸!!! - 说明没有优化#### 参考
  • 尾调用详解 - 阮一峰
  • go&plan9 - 曹大

什么是尾调用

```func g(n int) {fmt.Println(n)}func f(m int) {m++g(m)}在f()函数内最后直接调用g()
```

尾调用优化

  • 我们把调用函数称作caller,被调用函数称作callee
  • 在程序运行过程中,需要先保存caller现场在栈帧中,然后调用callee。caller栈帧会在callee调用返回后,继续执行完毕,然后释放
  • 但是,在尾调用中,callee在caller的最后,所以caller的栈帧其实在callee调用前就可以释放了,优化的目的也是为此
  • 提前释放释放caller栈帧,可大大减少内存使用,同时避免了调用层级过多导致的栈空间爆炸

尾递归调用

    ```func f(n int) {fmt.Println(n)n++f(n)}尾递归调用:在f()函数内最后再调用自己在C++等的O2级别优化中,一般会被优化为for循环
```

golang编译器是否会做尾递归优化

  • 从实验结果来看,不会做优化

验证方法一:查看汇编代码

  1. 写一个尾递归函数

  2. go tool compile -S demo.go 生成go-plan9汇编

验证方法二:编译运行

  1. 写一个尾递归函数,递归层级搞的足够大

  2. go run demo.go

  3. Boom!!! 内存爆炸!!!说明Golang编译器针对尾递归没有优化

[Golang]尾递归优化?相关推荐

  1. Kotlin尾递归优化

    一.尾递归优化 1.递归的一种特殊形式 2.调用自身后无其他的操作 3.tailrec关键字提示编译器尾递归优化 二.具体的来看看一下代码说明 package net.println.kotlin.c ...

  2. javascript --- 尾递归优化的实现

    考虑一个正常的递归函数 function sum(x, y) {if (y > 0) {return sum (x + 1, y - 1);} else {return x;} } sum(1, ...

  3. python 函数式编程尾递归优化 day16

    函数编程的特征: 1不可变:不用变量保存状态,不修改变量 #非函数式 a = 1 def incr_test1():global a#一旦更改全局变量后后面再调用a就容易乱a += 1return a ...

  4. 尾递归优化原理与Python实现(以Fibonacci数列和小明爬楼梯问题为例)

    首先祝全体屋友中秋节快乐! 众所周知,在函数递归调用时,要保存函数调用的位置以便使得被调函数结束后能够返回正确的位置,这个信息保存在线程栈中.由于栈的空间有限,所以如果函数递归调用深度超过一定限制,会 ...

  5. 尾递归优化 - 尾递归优化

    原理 调用一个函数时,就会形成一个调用帧:在A函数内部执行B函数:当调用A函数时形成一个A的调用帧,在A函数内部调用B函数,在A调用帧上又会生成B调用帧,B执行完毕时B调用帧消失,A完毕后A调用帧消失 ...

  6. python递归_Python开启尾递归优化!

    Python尾递归优化 一般递归与尾递归 一般递归: def normal_recursion(n): if n == 1: return 1 else: return n + normal_recu ...

  7. ES6 尾调用和尾递归优化

    尾调用 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function fun(x){return a(x); } 上面代码中,函数fun的最后一 ...

  8. java实现尾递归优化,你们都知道递归,尾递归呢?什么又是尾递归优化?

    你们都知道递归,尾递归呢?什么又是尾递归优化? 码农唐磊 程序猿石头 今天,咱们来聊聊递归函数.为啥忽然想到递归?其实就从电影名字<恐怖游轮><盗梦空间>想到了.图片java ...

  9. 大家都知道递归,尾递归呢?什么又是尾递归优化?

    点击上方蓝色字体,关注我 -- 一个在阿里云打工的清华学渣! 今天,我们来聊聊递归函数.为啥突然想到递归?其实就从电影名字<恐怖游轮><盗梦空间>想到了. 递归是啥? 递归函数 ...

最新文章

  1. Spark2.x写入Elasticsearch的性能测试
  2. 文件上传(上传至独立的文件服务器)
  3. iOS程序启动过程笔记
  4. 18亿用户、10万条电源线、4200万月活......创业者的底限究竟在哪里?
  5. android获取QQ昵称,【Ctrl.js】QQ读取好友昵称和QQ号源码
  6. 7.4.4 主成分分析 PCA
  7. 在欲而无欲,居尘不染尘
  8. JPA和Hibernate级联类型的初学者指南
  9. bat 存储过程返回值_MySQL-存储过程和函数详述
  10. [轉]VS2010 UML类图生成代码
  11. 使括号有效的最少添加
  12. JAVA创建对象有哪几种方式
  13. 华为交换机双上行组网Smart-link配置指南
  14. 工具类——FileUtils
  15. 嵌入式系统课堂总结1
  16. 四只头雁:5G to B规模商用的开启节点
  17. wlan从入门到精通第六期STA接入过程
  18. 【数据结构】栈和队列
  19. Chipsec UEFI Shell启动盘的制作与使用,让你可以在所有平台轻松使用Chipsec
  20. 基于金字塔LK的光流法实现—根据论文自己实现的c++代码

热门文章

  1. 无人驾驶实战(一)——车载摄像头行车视频车道线跟踪
  2. ffmpeg、ffplay、ffprobe 常用命令详解(音视频必备)
  3. QM/MM--GROMACS+CP2K 安装时报错
  4. 工作笔记一 --- 坐标点(point)
  5. 遗传算法原理以及MATLAB实现
  6. 三电平中点钳位(NPC)并网逆变器NCP逆变器-dq控制
  7. 基于Java办公自动化系统(OA)的设计技术及开发环境
  8. mysql 5.7.20 免安装版配置
  9. win7旗舰版出现COM Surrogate已停止工作
  10. 百度统计在项目中的使用