最近,在使用 Go 开发的时候,编译起来速度非常慢,之前没有遇到过这种情况,于是网上查资料,才知道好多用Go的小伙伴在 Windows上都碰到了这个邪门事儿:「明明就几行代码的程序,编译起来慢得要死,加个参数又突然变快了」。
这到底咋回事?今天就来唠唠这个让人头大的问题。
怪事:一行代码,两种速度
有个开发者在网上吐槽,说他写了个超级简单的Go程序(go 版本 go1.24.0 windows/amd64):
package main
func main() {
println("Hello, World!")
}
就这三行代码,「用go build编译居然要40多秒」,慢得让人怀疑人生。但他**「试了试加个参数-p=1」**,变成go build -p=1,嘿,瞬间就编译完了,连一秒都用不了。
更奇怪的是,他的电脑配置并不差:AMD 6800H 处理器、三星 980 PRO NVMe 固态硬盘,按理说编译这么简单的程序应该毫秒级完成。而且他在另一台配置类似的电脑(AMD 7745H、同型号 SSD)上也复现了这个问题,两台电脑都关闭了 Windows Defender,排除了系统自带安全软件的干扰。
查原因:参数藏玄机
为了找到原因,开发者用 Go 提供的调试工具做了分析
「详细过程如下」: 使用两种命令编译同一个文件,最后再用 actiongraph 工具分析。 (actiongraph 是 Go 官方提供的一个小工具,专门用来 "播放" 前面生成的 JSON 记录文件)
「1. 使用go build -debug-actiongraph="compile2.json" 命令编译」
-debug-actiongraph="compile.json"是个特殊参数,意思是:"编译的时候,把所有步骤(比如编译哪个文件、链接哪个库)的耗时、依赖关系都记录下来,存到一个叫 compile.json 的文件里
不加-p=1时,"build internal/godebugs" 这一步骤单独耗时 40.348 秒,占了总时间的 99.17%。
「2. 使用go build -p=1 -debug-actiongraph="compile.json"命令编译」
加-p=1时,各步骤耗时都在毫秒级,总耗时极短
从上述实验结果可以看到:「显然使用 -p=1 参数后速度就达到了正常,而不使用则需要 40s」。
作者本人也是同样的使用体验,直接 go build 编译项目,速度非常的慢~
「这里先简单解释下-p参数:它控制 Go 编译时的并行进程数,默认情况下,-p 的值等于你的 CPU 核心数(比如 8 核 CPU 就默认用 8 个进程并行编译),目的是充分利用多核优势,让多个编译步骤同时进行,加快整体速度。 理论上并行编译能加快速度,但在这里却成了 "拖油瓶"。」
社区接力:从怀疑 Go 本身到锁定第三方服务
这个问题很快引起了 Go 社区的关注。有开发者尝试复现,发现虽然没有 40 秒那么夸张,但确实存在 3 倍左右的速度差异;也有人猜测可能是 Go 的并行编译逻辑在 Windows 上有 bug。
直到一位网友的留言,才揭开了真相:
他提到自己也遇到了同样的问题,最终发现罪魁祸首是**「Microsoft PC Manager Service(微软电脑管家服务)」。 这个服务在 Windows 11 24H2 「更新后被默认安装并自启动」,会「在编译时疯狂扫描 Go 生成的临时文件,导致文件被频繁锁定,进而拖慢编译速度」**。 更关键的是,当他关闭这个服务后,编译速度立刻恢复正常;另一位网友直接卸载了微软电脑管家,编译速度也瞬间变快。
为什么-p=1能临时解决问题?
看到这里你可能会问:为什么加-p=1就能绕过这个问题?
原因其实很简单:
- 当-p为默认值(多进程并行)时,Go 会同时生成多个临时文件,微软电脑管家的实时扫描会频繁触发,导致文件操作阻塞;
- 当-p=1时,编译过程变成单进程串行执行,生成的临时文件少且有序,扫描冲突减少,所以速度变快。 但这只是临时解决方案,真正的问题根源还是第三方服务对编译过程的干扰。
解决方案:两步彻底解决编译慢问题
如果你也碰到这情况,试试这两个办法:
-
「临时应急:用-p=1参数」
编译的时候加上-p=1,命令这么写:- 「
go build -p=1」 简单粗暴,马上见效。
- 「
-
「彻底解决:关闭或卸载微软电脑管家」
- 打开任务管理器,找到"服务",找到
Microsoft PC Manager Service,右键停止,再禁用掉; - 要是根本不用这软件,直接在控制面板里卸载了,一了百了。
- 打开任务管理器,找到"服务",找到
总结
说白了,这个问题的本质,是**「第三方工具(微软电脑管家)的实时扫描与 Go 的并行编译逻辑在 Windows 上产生了冲突」。其实类似的情况并不少见:很多安全软件、系统管家类工具会监控临时文件操作,而编译过程恰好需要频繁创建 / 删除临时文件,两者很容易 "「撞车」**"。
以后要是碰到编译突然变慢,先别急着怀疑代码或编译器,看看后台是不是有啥程序在偷偷"捣乱"——有时候问题根本不在代码里,就藏在系统的某个小角落里呢。
你们碰到过这种离谱的问题吗?评论区聊聊~
参考资料
本文使用 markdown.com.cn 排版