You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言map传值拷贝问题解决方案:优化Collatz序列记忆化搜索性能

Go求解Collatz最长序列性能优化方案

求解Project Euler第14题时,暴力解法耗时0.5秒,引入记忆化搜索优化后仅提升到0.36秒,远低于预期。

认知误区修正

Go语言中map属于引用类型,函数传参时只会拷贝map的指针包装结构体(仅占几个字节),不会全量拷贝底层存储的键值数据,你之前检索到的「传map会全量拷贝」的结论是错误的,性能瓶颈另有原因。

现有代码性能瓶颈

  • 偶数计算存在多余的float64类型转换开销,直接做整数除法即可
  • 记忆化覆盖范围有限:仅缓存了初始输入值的序列长度,计算过程中产生的大于初始值的中间节点没有存入memo,浪费了大量重复计算

优化方案

代码修改示例

package main
// project euler 014 - longest collatz sequence
import (
	"fmt"
	"time"
)

func find_collatz_len(n int, memo map[int]int) int {
	if v, ok := memo[n]; ok {
		return v
	}
	var res int
	if n%2 == 0 {
		res = 1 + find_collatz_len(n/2, memo)
	} else {
		res = 1 + find_collatz_len(3*n+1, memo)
	}
	memo[n] = res
	return res
}

func main() {
	start := time.Now()
	max_length := 0
	number := 0
	memo := make(map[int]int)
	memo[1] = 1 // 边界条件初始化
	for i := 1; i < 1_000_000; i++ {
		current_length := find_collatz_len(i, memo)
		if current_length > max_length {
			max_length = current_length
			number = i
		}
	}
	fmt.Println(max_length, number)
	fmt.Println("Time:", time.Since(start).Seconds())
}

可选优化:消除传参开销

如果想要彻底避免map传参的微小开销,可以将memo声明为包级全局变量,不需要作为参数传入函数。

优化后代码运行耗时通常可以降到0.1秒以内,达到预期的性能提升效果。

内容的提问来源于stack exchange,提问作者Kolom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:24:07