静态缓存页面 · 查看动态版本 · 登录
智柴网 登录 | 注册
← 返回话题
✨步子哥 @steper · 2026-03-17 04:41

PureGo(ebitengine/purego) vs GoFFI(go-webgpu/goffi)完整对比 (数据截至 2026 年 3 月 16 日最新状态)

两者都是纯 Go、无 CGO 的 FFI 库,目标相同:CGO_ENABLED=0 就能调用任意 C 动态库(.so/.dll/.dylib)。但设计哲学、API 风格、性能侧重完全不同。

项目PureGo (ebitengine/purego)GoFFI (go-webgpu/goffi)
GitHubgithub.com/ebitengine/puregogithub.com/go-webgpu/goffi
Stars≈ 3.5k≈ 30(极小众)
最新版本v0.10.0(2026.2)v0.4.2(2026.3)
起源Ebitengine 游戏引擎团队(通用绑定)GoGPU/WebGPU 项目(GPU 计算专用)
成熟度高(Tier 1/2 广泛支持,已用于 chdb、GTK、libvips 等)中(专注 WebGPU,仍在快速迭代)

1. 设计思想对比(Design Philosophy)

  • PureGo“像写 Go 代码一样调用 C”
强调简单性 + 可维护性。使用反射 + 自动类型转换(string → C 字符串、slice 自动管理),开发者几乎感觉不到 FFI。目标是“解放 Go 开发者,不用学 ABI、不用写 unsafe”。 口号:最大可移植性 + 最小 boilerplate
  • GoFFI“像 libffi 一样极致性能 + 完全 ABI 控制”
强调零开销 + 实时计算(GPU/WebGPU、ML 推理、游戏渲染)。采用“prepare once, call many” 模式,预计算调用接口(CIF),手写汇编 trampoline,保证每调用零分配。 目标是解决 purego 在复杂结构体、浮点返回值、ARM64 HFA(Homogeneous Floating-point Aggregate)上的短板。 口号:GPU/高频场景的“原生速度”

一句话总结:PureGo 是“生产力工具”,GoFFI 是“极致性能引擎”

2. 架构设计对比

  • PureGo
  • 高层:RegisterFunc + reflect.MakeFunc 动态生成 wrapper。
  • 中层:fakecgo(完整复制 Go runtime/cgo 栈切换、callback)。
  • 底层:平台/架构特化汇编(dlfcn_*.s、zcallback_*.s),参数用 syscall15Args pooled。
  • 自动处理字符串、bool、slice。
  • GoFFI
  • 高层:LoadLibrary + GetSymbol + PrepareCallInterface(CIF)。
  • 中层:types.TypeDescriptor(手动描述 Size/Alignment/Kind)。
  • 底层:手写汇编 trampoline(每个进程预编译 2000 个入口,AMD64 仅 5 字节!)+ crosscall2(C 线程回调)。
  • 显式 ABI 控制(RAX+RDX、sret、XMM0、AAPCS64 HFA 递归检测)。
核心差异:PureGo 靠反射+pool 省心;GoFFI 靠预计算+纯汇编极致快。

3. 性能对比(官方数据)

GoFFI 在 README 公开 benchmark(Intel i7-1255U,AMD64):
  • 单次调用开销:88~114 ns(getpid 88ns,strlen 98ns,abs 114ns)。
  • 每调用零分配(CIF 可复用)。
  • 60 FPS × 50 调用/帧 = 仅 5µs/帧(占帧预算 0.03%)。
PureGo 未公开官方 ns 数字,但社区/dev.to 测试:
  • 使用 sync.Pool + reflect → 每调用 1~2 次 alloc,开销更高(约 150~250ns)。
  • GoFFI 在 GPU 热路径上通常快 30%~50%
CGO 参考:≈140ns(Go 1.26 优化后)。

4. 功能支持对比(核心表格)

(直接来自 GoFFI README + 2026.3 DEV.to 文章)

特性PureGoGoFFICGO
API 风格reflect RegisterFunc(一行注册)libffi 风格(Prepare CIF → CallFunction)原生
每调用分配有(pool)
结构体传参/返回部分(Windows 弱)完整(RAX+RDX、sret)完整
回调返回 float(XMM0)panic支持支持
ARM64 HFA(嵌套浮点结构体)部分 bug完整递归检测支持
字符串/切片自动转换优秀(自动 null + KeepAlive)仅 raw pointer(需手动)优秀
Context 超时/取消支持(CallFunctionContext)
C 线程回调支持支持(crosscall2)支持
平台覆盖8+ GOARCH / 20+ OS6 核心(Win/Linux/macOS × amd64/arm64)
Typed Error泛型 error5 种强类型 + errors.AsN/A
Variadic 函数支持暂不支持(v0.5 计划)支持

5. 使用示例对比(strlen)

PureGo(简单)
lib, _ := purego.Dlopen("libc.so.6", purego.RTLD_NOW)
var strlen func(unsafe.Pointer) uint64
purego.RegisterLibFunc(&strlen, lib, "strlen")
fmt.Println(strlen(unsafe.Pointer(unsafe.StringData("hello\x00"))))

GoFFI(显式但更快)

handle, _ := ffi.LoadLibrary("libc.so.6")
sym, _ := ffi.GetSymbol(handle, "strlen")
cif := &types.CallInterface{}
ffi.PrepareCallInterface(cif, types.DefaultCall, types.UInt64TypeDescriptor,
    []*types.TypeDescriptor{types.PointerTypeDescriptor})
var length uint64
strPtr := uintptr(unsafe.StringData("hello\x00"))
ffi.CallFunction(cif, sym, unsafe.Pointer(&length), []unsafe.Pointer{unsafe.Pointer(&strPtr)})

6. 优缺点总结

PureGo 优势
  • 代码最少、最易上手
  • 字符串/slice 自动处理
  • 平台支持最广(含 ppc64le、riscv64、s390x)
  • 社区生态成熟
GoFFI 优势
  • 性能碾压(零分配 + 更优 ABI)
  • 复杂结构体、浮点回调、ARM64 HFA 更强
  • Context 支持、typed error、更安全
  • 专为 GPU/WebGPU 设计(wgpu-native 官方绑定)
共同缺点:都不支持 bitfield、Windows C++ 异常(需 panic=abort)。

7. 适用场景推荐

  • 选 PureGo:普通绑定(libpng、SDL、GTK、数据库、插件系统)、需要多平台、追求开发速度的项目。大多数开发者首选
  • 选 GoFFI:GPU 计算、WebGPU、实时渲染、ML 推理、高频循环调用(>10万次/秒)、对结构体/浮点回调有强需求。GoGPU 项目已全面采用
  • 两者共存:可行,但注意 linker 冲突(用 build tag 分离)。
未来:Go 官方提案 #77386(x/tools/ffi)正在讨论“原生 FFI 生成工具”,很可能参考两者优点。GoFFI 正在追赶平台广度,PureGo 也在优化回调结构体(2026.3 已支持)。

结论PureGo = 生产力王者(3.5k stars 证明一切) GoFFI = 性能王者(GPU 场景必备)

如果你是做游戏/图形/AI 推理,强烈推荐试 GoFFI;普通系统集成,继续用 PureGo 就够了。

Repo 链接:

  • PureGo:https://github.com/ebitengine/purego
  • GoFFI:https://github.com/go-webgpu/goffi (带详细 PERFORMANCE.md)

👍 2