Go 和 Rust 编译后程序大小对比

学习笔记作者:admin日期:2025-09-26点击:11

摘要:Rust 编译后的程序通常比 Go 更小,尤其是在启用优化和代码瘦身选项后。Go 默认包含运行时和调试信息,而 Rust 则更轻量,适合对体积敏感的场景。

1. 默认编译输出大小对比

语言 默认编译大小特点
Go 默认生成的二进制文件较大,包含完整的运行时(GC、goroutine 调度器等)、调试信息和标准库静态链接。即使一个简单的 "Hello World" 也可能在几 MB 左右(例如 2-5 MB)。
Rust 默认生成的二进制文件更小,尤其是对小型项目。Rust 是零成本抽象语言,标准库精简,且默认不包含垃圾回收等运行时。Hello World 可能只有几百 KB。

2. 影响二进制大小的关键因素

Go

  • 静态链接:Go 默认将所有依赖(包括运行时)打包进一个二进制文件。
  • 运行时开销:包含 GC、goroutine 调度、反射、类型信息等,即使不用也包含。
  • 调试信息:默认包含 DWARF 调试信息,显著增加体积。
  • 可优化go build -ldflags="-s -w" 去除符号表和调试信息,可大幅减小体积。
  • UPX 压缩:进一步减小(但运行时解压)。

Rust

  • 零成本抽象:未使用的代码不会被编译进去(得益于单态化和死代码消除)。
  • 运行时极小:无 GC,运行时非常轻量,甚至可以使用 no_std 编写无运行时程序。
  • 编译器优化:通过 LTO(链接时优化)、opt-level=s(大小优化)等可显著减小体积。
  • 可配置:可通过 strip 去除调试符号,或使用 cargo-bloat 分析体积来源。

3. 示例对比(Hello World)

// main.go
package main
import "fmt"
func main() {
    fmt.Println("Hello, World!")
}
// main.rs
fn main() {
    println!("Hello, World!");
}
语言 编译命令 输出大小(约)
Go go build main.go 2.5 MB
Go go build -ldflags="-s -w" main.go 1.3 MB
Rust cargo build --release 300 KB
Rust cargo build --release + strip ~150 KB

4. 什么时候 Go 可能更小?

  • 几乎不会。
  • 除非:
    • Rust 项目使用了大量泛型(导致代码膨胀)。
    • Go 程序极简且经过深度优化(如 TinyGo,用于嵌入式,可生成极小二进制)。

      TinyGo 是一个特例:它使用 LLVM,专为嵌入式设计,可生成比 Rust 更小的二进制(在微控制器上),但功能受限。

5. 总结:哪个更小?

      Rust 通常生成更小的二进制文件,尤其适合对体积敏感的场景(CLI 工具、嵌入式、WASM)。

      Go 二进制较大,但开发效率高、部署方便(单文件、自带运行时),适合后端服务。

6. 如何减小体积?

Go

go build -ldflags="-s -w" -o main main.go
# 进一步压缩
upx --best --lzma main

Rust

[profile.release]
opt-level = "s"    # 或 "z"(最小尺寸)
lto = true
strip = true       # 自动 strip(需 nightly)
# 编译后 strip
strip target/release/main
# 或使用 upx
upx --best --lzma target/release/main

结论

      如果你关心二进制大小,Rust 通常是更好的选择。

      如果你更看重开发效率和部署简单,Go 仍然非常有竞争力,尽管体积大一些。

上一篇