首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go 的 Map 为什么变慢了?来看 Go 1.25 要怎么修复它

Go 的 Map 为什么变慢了?来看 Go 1.25 要怎么修复它

作者头像
萝卜要努力
发布2025-05-21 14:35:32
发布2025-05-21 14:35:32
6080
举报
文章被收录于专栏:萝卜要加油萝卜要加油

这篇文章解释了为什么在 Go 1.24 版本中,你的程序可能因为 map 变慢了,以及 Go 团队是怎么计划修复这个问题的。

Golang 1.24 中最吸引我的功能就是 SwissMap,在以前的非官方实现中,有些场景能够提升50% 的性能,官方的实现中,也有不小的性能提升。 详情参考我以前的文章: SwissTable会成为Golang标准map的实现嘛?

但是 如果你在使用 Go 1.24 时可能会发现SwissMap 没有达到预期的表现,甚至程序运行变慢了,特别是在 Map很大的时候,这不是你的幻觉,确实存在这个问题。![[Pasted image 20250520195831.png]] https://x.com/valyala/status/1879988053076504761[1]

这个问题记录在 Issue #70835[2] 中,开发者们正在努力解决它。

问题出在哪?

Go 的 map 在新版中使用了Swiss Table,它在小 map 和高并发的场景下非常快。但是当 map 很大、数据又不在 CPU 缓存里(也就是说,数据是“冷”的),就会变慢。

为什么会这样呢?

因为 SwissMap 的内部结构比较复杂,它会分几层来存储数据:

  1. 首先是一个 map 的头部结构
  2. 它指向一个目录,这个目录是多个 table 的指针组成的列表
  3. 每个 table 里面有控制信息、key 和 value

当你查找一个 key 的时候,可能需要进行 4 到 6 次跳转,每一次都可能遇到缓存未命中。这样就会导致 CPU 忙着从内存取数据,速度就慢了。

像 Prometheus 这样的大型项目就发现了这个问题。他们升级到 Go 1.24 后,CPU 使用率上升了很多,经调查发现就是因为 map 的查找变慢了。

是怎么发现的?

问题并不是在测试用例里发现的,而是在真实的线上场景中出现的。

  • 使用了很大的 map(比如几兆字节大小)
  • 经常读取 map 里的数据
  • 数据不在 CPU 的高速缓存里

Go 团队的工程师 Michael Pratt 通过做很多测试,找到了 map 访问变慢的原因,并在 Issue #70835[2] 中详细说明。

怎么修?

为了让 map 更快,他们计划做以下几件事:

  • 简化目录结构:把原来存指针的列表改成直接存结构,减少一次跳转
  • 控制信息更紧凑:把控制信息安排得更集中,这样更容易被 CPU 一次加载
  • 分离 key 和 value:改成“key-key-key + value-value-value”的结构,这样可以优化加载顺序
  • 对齐控制字节:把控制信息按照 CPU 缓存对齐,减少未命中

这些改动并不简单,因为会影响到 Go 的运行时核心:

  • 要确保垃圾回收能正常工作
  • map 扩容和缩容逻辑要更新
  • 要确保对小 map 的性能没有影响

哪些地方在讨论这个?

这个问题被广泛讨论和跟踪,可以通过Issue #70835[2] 了解更多的 细节。 Go Release Dashboard[3] 中已经标记这个问题将会在 Go1.25 中解决 此外 Issue #71368[4] 中也讨论了 另一个与内存布局的问题。

总结

Go 团队一直在努力让语言运行得更快更稳。SwissMap 是个好改进,但它也带来了新挑战,比如这次的冷缓存性能下降。 Issue #70835 展示了 Go 是如何通过社区反馈不断进步的。感谢像 Prometheus 这样的开源项目,他们的报告帮助 Go 做得更好。 如果一切顺利,Go 1.25 就能把速度和稳定性都带回来。 我们一起期待吧!

引用链接

[1]https://x.com/valyala/status/1879988053076504761

[2]Issue #70835: https://github.com/golang/go/issues/70835

[3]Go Release Dashboard: https://github.com/golang/go/milestone/122

[4]Issue #71368: https://github.com/golang/go/issues/71368


Green Tea GC: Golang 的 ZGC?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萝卜要加油 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题出在哪?
  • 是怎么发现的?
  • 怎么修?
  • 哪些地方在讨论这个?
  • 总结
    • 引用链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档