Go1.24 新特性:sync.Map 性能提高、Go mod 增加 tool 指令、net/http 协议优化等

大家好,我是煎鱼。

今天给大家继续介绍 Go1.24 的新特性。

sync.Map 性能优化

由 @Michael Knyszek 大佬提出的提案:

其首先在 unique 包中添加了 HashTrieMap。随后在很多场景下,发现比传统的 Map 性能和速度高效很多。

因此 Go 核心团队重新实现了 sync.Map 基于 HashTrieMap 实现方案。在本次的新版本 Go1.24 中,sync.Map 已经改为并发的 HashTrieMap 数据结构。在性能上有了显著的提高。

如果你不希望使用,也可以通过配置 GOEXPERIMENT=nosynchashtriemap 来恢复到旧版本。

以下是两者的前后性能对比:

/gomaxprocs: 4
                                │     before      │                 after                 │
                                │     sec/op      │    sec/op      vs base                │
MapLoadMostlyHits                   7.870n ±   1%    8.415n ±  3%    +6.93% (p=0.002 n=6)
MapLoadMostlyMisses                 7.210n ±   1%    5.314n ±  2%   -26.28% (p=0.002 n=6)
MapLoadOrStoreBalanced             360.10n ±  18%    71.78n ±  2%   -80.07% (p=0.002 n=6)
MapLoadOrStoreUnique                707.2n ±  18%    135.2n ±  4%   -80.88% (p=0.002 n=6)
MapLoadOrStoreCollision             5.089n ± 201%    3.963n ±  1%   -22.11% (p=0.002 n=6)
MapLoadAndDeleteBalanced           17.045n ±  64%    5.280n ±  1%   -69.02% (p=0.002 n=6)
MapLoadAndDeleteUnique             14.250n ±  57%    6.452n ±  1%         ~ (p=0.368 n=6)
MapLoadAndDeleteCollision           19.34n ±  39%    23.31n ± 27%         ~ (p=0.180 n=6)
MapRange                            3.055µ ±   3%    1.918µ ±  2%   -37.23% (p=0.002 n=6)
MapAdversarialAlloc                245.30n ±   6%    14.90n ± 23%   -93.92% (p=0.002 n=6)
MapAdversarialDelete              143.550n ±   2%    8.184n ±  1%   -94.30% (p=0.002 n=6)
MapDeleteCollision                  9.199n ±  65%    3.165n ±  1%   -65.59% (p=0.002 n=6)
MapSwapCollision                    164.7n ±   7%    108.7n ± 36%   -34.01% (p=0.002 n=6)
MapSwapMostlyHits                   33.12n ±  15%    35.79n ±  9%         ~ (p=0.180 n=6)
MapSwapMostlyMisses                 604.5n ±   5%    280.2n ±  7%   -53.64% (p=0.002 n=6)
MapCompareAndSwapCollision          96.02n ±  40%    69.93n ± 24%   -27.17% (p=0.041 n=6)
MapCompareAndSwapNoExistingKey      6.345n ±   1%    6.202n ±  1%    -2.24% (p=0.002 n=6)
MapCompareAndSwapValueNotEqual      6.121n ±   3%    5.564n ±  4%    -9.09% (p=0.002 n=6)
MapCompareAndSwapMostlyHits         44.21n ±  13%    43.46n ± 11%         ~ (p=0.485 n=6)
MapCompareAndSwapMostlyMisses       33.51n ±   6%    13.51n ±  5%   -59.70% (p=0.002 n=6)
MapCompareAndDeleteCollision        27.85n ± 104%    31.02n ± 26%         ~ (p=0.180 n=6)
MapCompareAndDeleteMostlyHits       50.43n ±  33%   109.45n ±  8%  +117.03% (p=0.002 n=6)
MapCompareAndDeleteMostlyMisses     27.17n ±   7%    11.37n ±  3%   -58.14% (p=0.002 n=6)
MapClear                            300.2n ±   5%    124.2n ±  8%   -58.64% (p=0.002 n=6)
geomean                             50.38n           25.79n         -48.81%

go.mod 新增 tool 指示符

由 @Michael Tibben 大佬提出的新提案《Proposal: Adding tool dependencies to go.mod[1]》:

问题的背景是:

  1. Go 开发者经常使用由 Go 编写并作为 Go 模块分发的工具。例如:golang.org/x/tools/cmd/stringergithub.com/kyleconroy/sqlc

  2. 但是当前对这些 Go 开发的工具的模块管理支持相对薄弱。没法很好的进行周知和管理。

为了解决这一个问题,提案作者提议在 go.mod 文件中引入一个新的 tool 指令,使工具开发的作者能够定义工具所需的模块和相关版本。

go.mod 文件的例子如下:

go 1.24

tool (
    golang.org/x/tools/cmd/stringer
    ./cmd/migrate
)

等效于:

go 1.24

tool golang.org/x/tools/cmd/stringer
tool ./cmd/migrate

在使用中,我们也可以在命令行编写 go get 命令往 go.mod 文件追加:

go get -tool golang.org/x/tools/cmd/stringer

会是以下效果:

module example

go 1.24

tool golang.org/x/tools/cmd/stringer
...

本次通过在 go.mod 中引入 tool 指令,开发者们可以更方便地管理项目所需的工具,确保团队成员使用相同版本的工具,避免版本不一致的问题。

net/http Protocols 使用优化

在以往的 net/http 标准库中,提案原作者 @Damien Neil 认为原有的用于选择协议版本的 API 容易混淆、不一致、暴露内部实现细节,而且不能很好地推广到其他协议版本。

因此新提案作者建议用一种单一、清晰的机制取代它们,并允许未来进行扩展。

采取的方式是提供以下新方法:

type Protocols struct { ... }
func (p *Protocols) HTTP1() bool
func (p *Protocols) HTTP2() bool
func (p *Protocols) HTTP3() bool
func (p *Protocols) SetHTTP1(ok bool)
func (p *Protocols) SetHTTP2(ok bool)
func (p *Protocols) SetHTTP3(ok bool)

代码例子:

...
 t.Protocols = new(http.Protocols)
 t.Protocols.SetHTTP1(true)
 t.Protocols.SetHTTP2(true)
 &http.Client{Transport: t}
 ...

总结

本次这部分的 Go1.24 新特性中,针对 sync.map 也进行了综合性能优化。综合之前文章提到的 map 的综合性能提高。本次 Go1.24 对于较为常用的两个数据结构都有了明确的提高。是非常赞的!

另外本文也提及了 go.mod 的 tools 和 net/http Protocols 的使用优化,也算是一些小点的优化了。

推荐阅读

参考资料

[1]

Proposal: Adding tool dependencies to go.mod: https://go.googlesource.com/proposal/+/54d6775ff71ccbc00c276db2a4e4841d67011cf4/design/48429-go-tool-modules.md

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

7a6172c17405aa83508313b0fa670397.jpeg

9750db2ea5b9f4d04860896881aabe56.png

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值