如何让Golang项目构建速度更快

如何让Golang项目构建速度更快 卸载Go以进行升级 我在Windows/amd64上安装了go1.15.5。 为了确认,当我运行 go run main.go 时,构建没有完成。 我等待了40分钟,它仍未完成。 这是有原因的吗?还是规范发生了变化? 如何更快地完成 go run main.go

6 回复

重新安装操作系统解决了这个问题。

更多关于如何让Golang项目构建速度更快的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


没有更多信息,无法判断发生了什么。

  • 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 安装说明操作的?

Go:下载与安装

如果你按照官方的 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

关键检查点:

  1. 网络问题(依赖下载):设置正确的GOPROXY
  2. 杀毒软件干扰:排除Go目录
  3. 磁盘IO瓶颈:使用SSD并清理磁盘空间
  4. 内存不足:确保至少4GB可用内存
  5. 循环依赖:检查import循环

先执行 go clean -cache 并设置代理,这通常能解决80%的构建缓慢问题。如果特定项目仍有问题,提供 go env 输出和项目结构可进一步分析。

回到顶部