如何让Golang项目构建速度更快
如何让Golang项目构建速度更快
卸载Go以进行升级
我在Windows/amd64上安装了go1.15.5。
为了确认,当我运行 go run main.go 时,构建没有完成。
我等待了40分钟,它仍未完成。
这是有原因的吗?还是规范发生了变化?
如何更快地完成 go run main.go?
没有更多信息,无法判断发生了什么。
main.go具体是什么?它是小型还是大型文件?- 你是否使用了任何模块或库?是哪些?
- 如果执行
go build会发生什么?
抱歉,信息提供不足…… main.go 文件具体是什么情况?它是小文件还是大文件? 答:是的,它很小,795字节。 你是否使用了任何模块或库?是哪些? 答:是的,使用了以下库:
"fmt"
"regexp"
"net/http"
"io/ioutil"
"log"
"strings"
如果你执行 go build 会发生什么? 答:我尝试了 go build,它和 go run 一样没有完成。
代码:
package main
import (
"fmt"
"regexp"
"net/http"
"io/ioutil"
"log"
"strings"
)
func CheckError(err error) {
if err != nil {
fmt.Println(a)
log.Fatal(err)
}
}
var (
recmp = regexp.MustCompile("\\<([\\w\\W])+?\\>")
recmp_script = regexp.MustCompile("\\<script([\\w\\W])>([\\w\\W])<script\\>")
inp_deletion = strings.NewReplacer("\n","","\t",""," ","")
)
func main(){
url := "https://youtube.com"
resp, err := http.Get(url)
CheckError(err)
defer resp.Body.Close()
bodys, err := ioutil.ReadAll(resp.Body)
CheckError(err)
a := recmp.ReplaceAllString(inp_deletion.Replace(recmp_script.ReplaceAllString(string(bodys),"")),"")
fmt.Println(a)
}
我使用的操作系统是 Windows 10。
petrus:
您是否严格遵循了Windows的官方安装说明?
A. 是的,我彻底卸载并重新安装了,因为可能之前某个地方出了错。
petrus:
go version命令的输出是什么?
A. 输出如下
Microsoft Windows [Version 10.0.18363.1198]
(c) 2019 Microsoft Corporation. All rights reserved.
>go version
go version go1.15.5 windows/amd64
petrus:
运行这个简单的
hello.go程序会怎样?
A. 运行得非常完美!这是输出
>go run hello.go
Hello, Gophers!
petrus:
运行这个简单的
example.go程序会怎样?
A. 什么都没有出现!甚至连错误都没有发生!
>go run example.go
petrus:
go env命令的输出是什么?
A. go env 成功输出了以下内容(*为保护隐私,用户信息已打码)
set GO111MODULE=
set GOARCH=amd64
set GOBIN=GOPATH/bin
set GOCACHE=C:\Users\UsersName\AppData\Local\go-build
set GOENV=C:\Users\UsersName\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\UsersName\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\UsersName\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\UsersName\AppData\Local\Temp\go-build210965470=/tmp/go-build -gno-record-gcc-switches
fea_kafea:
我在 windows/amd64 上安装了 go1.15.5。 为了确认,当我运行
go run main.go时,构建没有完成。
fea_kafea:
抱歉信息不足…
我无法复现你的问题,即使在我修复了你程序中的编译错误之后。
请提供如何复现你问题的精确步骤。
我在 windows/amd64 上安装了 go1.15.5。
你是否严格按照官方的 Windows 安装说明操作的?
如果你按照官方的 Windows 安装说明重新下载并安装,会发生什么?
你运行 go version 命令的输出是什么?
Microsoft Windows [Version 10.0.19041.572]
(c) 2020 Microsoft Corporation. All rights reserved.
>go version
go version go1.15.5 windows/amd64
你把事情搞得太复杂了。保持简单。
当你运行这个简单的 hello.go 程序时会发生什么?
package main
import "fmt"
func main() {
fmt.Println("Hello, Gophers!")
}
>go run hello.go
Hello, Gophers!
当你运行这个简单的 example.go 程序时会发生什么?
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
url := "https://example.com"
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(len(body))
fmt.Println(string(body))
}
>go run example.go
1256
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
你运行 go env 命令的输出是什么?
针对你的情况,go run main.go 长时间未完成通常与Go版本升级无关,更可能是项目依赖或环境配置问题。以下是具体排查步骤和优化构建速度的方案:
1. 立即诊断当前卡住的原因
先中断当前进程,然后运行以下命令诊断:
# 查看详细构建过程,找到卡住的环节
go build -x main.go
# 清理缓存和临时文件
go clean -cache
go clean -modcache
# 检查模块依赖
go list -m all
2. 优化构建速度的配置
启用Go Modules并设置代理(国内用户必需)
# 设置环境变量(Windows PowerShell)
$env:GO111MODULE = "on"
$env:GOPROXY = "https://goproxy.cn,direct"
$env:GOSUMDB = "sum.golang.google.cn"
# 永久设置(系统环境变量)
# GO111MODULE=on
# GOPROXY=https://goproxy.cn,direct
# GOSUMDB=sum.golang.google.cn
使用并行编译和缓存
# 设置并行编译数量(CPU核心数)
$env:GOFLAGS = "-p=8"
# 验证构建缓存位置
go env GOCACHE
3. 项目级优化配置
在项目根目录创建 Makefile:
.PHONY: build run fast
# 快速构建(跳过测试和代码检查)
fast:
@echo "快速构建中..."
go build -ldflags="-s -w" -trimpath -o ./bin/app main.go
# 带缓存的运行
run:
go run -race main.go
# 清理构建缓存
clean:
go clean -cache -testcache -modcache
创建 .golangci.yml 优化检查:
run:
timeout: 5m
modules-download-mode: readonly
linters-settings:
gocyclo:
min-complexity: 20
govet:
check-shadowing: true
4. 代码层面的构建优化
减少init()函数的使用
// 避免在init()中做耗时操作
var config *Config
// 改为懒加载
func GetConfig() *Config {
if config == nil {
config = loadConfig() // 按需加载
}
return config
}
使用构建标签分离代码
// +build debug
package main
func init() {
// 仅调试时编译的代码
setupDebugTools()
}
5. 针对Windows的特定优化
# 禁用杀毒软件实时扫描Go工作目录
# 将以下目录添加到杀毒软件排除列表:
# - %USERPROFILE%\go
# - %USERPROFILE%\AppData\Local\go-build
# - 项目目录
# 使用固态硬盘存储Go工作区
$env:GOPATH = "D:\go-workspace" # SSD路径
# 调整文件系统缓存
$env:GODEBUG = "asyncpreemptoff=1"
6. 如果问题依旧存在,进行深度排查
# 1. 创建最小复现案例
mkdir test-app && cd test-app
go mod init test
echo 'package main\n\nfunc main() {\n println("hello")\n}' > main.go
# 2. 测试基础构建(应该立即完成)
time go run main.go
# 3. 如果基础构建正常,逐步添加原项目文件
# 4. 使用性能分析
go build -gcflags="-m -m" main.go 2> analysis.txt
7. 构建监控脚本
创建 build_monitor.go:
package main
import (
"context"
"fmt"
"os/exec"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
defer cancel()
start := time.Now()
cmd := exec.CommandContext(ctx, "go", "build", "-v", "main.go")
output, err := cmd.CombinedOutput()
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
fmt.Println("构建超时(2分钟)")
// 分析卡住位置
fmt.Printf("最后输出:\n%s\n", output[len(output)-500:])
}
return
}
fmt.Printf("构建完成,耗时:%v\n", time.Since(start))
}
运行诊断:
go run build_monitor.go
关键检查点:
- 网络问题(依赖下载):设置正确的GOPROXY
- 杀毒软件干扰:排除Go目录
- 磁盘IO瓶颈:使用SSD并清理磁盘空间
- 内存不足:确保至少4GB可用内存
- 循环依赖:检查import循环
先执行 go clean -cache 并设置代理,这通常能解决80%的构建缓慢问题。如果特定项目仍有问题,提供 go env 输出和项目结构可进一步分析。

