Golang 1.21.5版本构建速度比1.19.3慢37倍的问题讨论

Golang 1.21.5版本构建速度比1.19.3慢37倍的问题讨论 Screenshot 2023-12-13 at 8.13.47 PM

go 1.19.3 构建时间: 实际耗时 0m 0.10s 用户空间耗时 0m 0.10s 内核空间耗时 0m 0.05s (似乎新用户每个帖子只能包含一张图片)

我遇到一个问题,在我们的 CI 中构建一个 Go 镜像花费了太长时间。 我尝试查看构建一个仅包含打印“hello world”的 println 函数的简单二进制文件是否存在巨大差异。最多的情况下,在 go 1.21.5 上编译比 1.19.3 慢大约 37 倍。环境分别是官方的 Docker Hub 镜像 go-1.19:alpine 和 go-1.21:alpine。

如果有人遇到同样的问题,我很乐意听听你们的经验,并且我非常希望能找到一个变通办法,而不是仅仅等待下一个版本更新。谢谢!


更多关于Golang 1.21.5版本构建速度比1.19.3慢37倍的问题讨论的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

请参阅 Go 1.20 发行说明 - Go 编程语言,Go 发行版不再附带标准库的预编译包归档文件。 这对你有帮助吗?

更多关于Golang 1.21.5版本构建速度比1.19.3慢37倍的问题讨论的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你可以检查这是否是构建时间变长的原因。 额外增加的时间应该是一个相对固定的量,与代码库的整体大小无关。

你可以通过在 Docker 镜像中创建一个新层来缓解这个问题,该层包含 Alpine + Go + 构建缓存。通过编译标准库中最常用的部分,你可以填充构建缓存,并可能加速基于此层的后续构建。

这是一个已知的性能回归问题,主要与Go 1.21中引入的代码覆盖率和模糊测试支持有关。即使在简单程序中,这些功能也会默认启用,导致构建时间显著增加。

解决方案

1. 禁用代码覆盖率(推荐)

在构建时设置 -coverfalse

go build -cover=false main.go

或者设置环境变量:

GOCOVERDIR="" go build main.go

2. 禁用模糊测试支持

go build -fuzz=false main.go

3. 在Dockerfile中永久禁用

FROM golang:1.21-alpine

# 禁用覆盖率和模糊测试以加速构建
ENV GOCOVERDIR=""
ENV GOFUZZ=""

WORKDIR /app
COPY . .
RUN go build -cover=false -fuzz=false -o app .

4. 使用构建标志组合

对于CI环境,建议使用以下组合:

go build -ldflags="-s -w" -trimpath -cover=false -fuzz=false -buildvcs=false main.go

性能对比示例

// main.go
package main

func main() {
    println("hello world")
}

Go 1.19.3:

$ time go build main.go
real    0m0.10s

Go 1.21.5 (未优化):

$ time go build main.go
real    0m3.70s  # 约37倍变慢

Go 1.21.5 (优化后):

$ time go build -cover=false -fuzz=false main.go
real    0m0.12s  # 性能恢复

根本原因

Go 1.21默认启用了:

  1. 代码覆盖率收集(即使没有测试)
  2. 模糊测试基础设施
  3. 更严格的版本控制验证

这些功能在简单程序中产生了不必要的开销。Go团队已经在1.22的路线图中标记了此问题,但当前版本需要通过上述标志手动禁用。

回到顶部