关于 Go 递归性能的疑问

2024-09-03 13:58:36 +08:00
 zedpass

OP 是 Go 语言初学者,学到递归这里实现斐波那契数列的计算,看到的资料都说 Go 没有对尾递归做优化,但是我用尾递归的方式测试之后,发现性能会比最原始的递归方式强非常多,这是什么原因呢?

package main

import (
	"fmt"
	"time"
)

func fibonacciTailRecursive(n int, a int, b int) int {
	if n == 0 {
		return a
	}
	return fibonacciTailRecursive(n-1, b, a+b)
}

func fib(n int) int {
	if n <= 1 {
		return n
	}
	return fib(n-1) + fib(n-2)
}
func fib1(n int) int {
	return fibonacciTailRecursive(n, 0, 1)
}

func main() {
	n := 40
	start := time.Now()
	result := fib(n)
	duration := time.Since(start)
	fmt.Println(result, duration) // 常规的递归结果 102334155 394.601829ms

	start = time.Now()
	result = fib1(n)
	duration = time.Since(start)
	fmt.Println(result, duration) // 使用尾递归结果 102334155 90ns
}
998 次点击
所在节点    Go 编程语言
4 条回复
Leviathann
2024-09-03 14:03:10 +08:00
尾递归没有优化,是说依然有那么深的 callstack ,其他就几乎和迭代法一致

原始的递归方法慢,是因为有大量重复计算的问题
everfly
2024-09-03 14:06:17 +08:00
你这两种算法的复杂度都不一样。
PTLin
2024-09-03 14:08:15 +08:00
你这一个自顶而下的 dp 算法和一个自底而上的版本比性能,你居然还会对速度有疑问,你这完全就是 dp 没学好。
archxm
2024-09-03 14:13:33 +08:00
dp 动态规划,会缓存结果的。用啥语言都一样。
其实学生不必在意性能问题。实际工作,跑一跑,就知道了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1069883

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX