Golang Go语言中推广支持proto3的protobuf生成工具,欢迎来找虫

发布于 1周前 作者 yibo5220 来自 Go语言

失业在家,把原来用到的 protobuf 工具代码整理了一下,发个支持 proto3 的生成工具,目前只支持 proto3 格式 生成的 Marshal 、MarshalTo 和 Unmarshal 方法参考 gogoprotobuf 的实现。

地址:https://github.com/billyplus/fastproto

Marshal message

    msg := &pb.SomeProtoMsg{}
    if err := fastproto.Marshal(msg); err!=nil {}
// 预告分配好空间
data := make([]byte, msg.Size())
if n, err := fastproto.MarshalTo(data, msg); err!=nil {}
// 可以用 data[:n]获取结果

Unmarshal message

    msg := &pb.SomeProtoMsg{}
    if err := fastproto.Unmarshal(data, &msg); err!=nil {}

性能对比

提升有 30%到 70%

goos: linux
goarch: amd64
pkg: github.com/billyplus/fastproto/test
cpu: AMD Ryzen 9 5950X 16-Core Processor            
  |                                  |          |              |            |                |
  | -------------------------------- | -------- | ------------ | ---------- | -------------- |
  | **FastMarshalStringSlice-6**     | 14644707 | 81.75 ns/op  | 80 B/op    | 1 allocs/op    |
  | StandardMarshalStringSlice-6     | 8223910  | 144.4 ns/op  | 80 B/op    | 1 allocs/op    |
  | **FastMarshalBytesSlice-6**      | 13065022 | 93.40 ns/op  | 80 B/op    | 1 allocs/op    |
  | StandardMarshalBytesSlice-6      | 10043254 | 124.9 ns/op  | 80 B/op    | 1 allocs/op    |
  | **FastMarshalInt32Slice-6**      | 5772819  | 213.1 ns/op  | 128 B/op   | 1 allocs/op    |
  | StandardMarshalInt32Slice-6      | 5056791  | 237.5 ns/op  | 128 B/op   | 1 allocs/op    |
  | **FastMarshalSint64Slice-6**     | 4123633  | 288.3 ns/op  | 224 B/op   | 1 allocs/op    |
  | StandardMarshalSint64Slice-6     | 3811389  | 311.4 ns/op  | 224 B/op   | 1 allocs/op    |
  | **FastMarshalSfixed32Slice-6**   | 16257074 | 73.97 ns/op  | 112 B/op   | 1 allocs/op    |
  | StandardMarshalSfixed32Slice-6   | 12917850 | 93.63 ns/op  | 112 B/op   | 1 allocs/op    |
  | **FastMarshalSfixed64Slice-6**   | 14003510 | 89.69 ns/op  | 208 B/op   | 1 allocs/op    |
  | StandardMarshalSfixed64Slice-6   | 11058189 | 115.9 ns/op  | 208 B/op   | 1 allocs/op    |
  | **FastMarshalToMixedProto-6**    | 74734    | 15354 ns/op  | 0 B/op     | 0 allocs/op    |
  | **FastMarshalMixedProto-6**      | 43844    | 27804 ns/op  | 18432 B/op | 1 allocs/op    |
  | StandardMarshalMixedProto-6      | 12552    | 94428 ns/op  | 37664 B/op | 1521 allocs/op |
  | **FastSizeMixedProto-6**         | 205432   | 6061 ns/op   | 0 B/op     | 0 allocs/op    |
  | StandardSizeMixedProto-6         | 32412    | 39230 ns/op  | 9616 B/op  | 760 allocs/op  |
  | **FastUnmarshalStringSlice-6**   | 4322337  | 291.3 ns/op  | 314 B/op   | 7 allocs/op    |
  | StandardUnmarshalStringSlice-6   | 3088686  | 384.5 ns/op  | 314 B/op   | 7 allocs/op    |
  | **FastUnmarshalBytesSlice-6**    | 3194150  | 376.0 ns/op  | 448 B/op   | 8 allocs/op    |
  | StandardUnmarshalBytesSlice-6    | 2770154  | 426.6 ns/op  | 448 B/op   | 8 allocs/op    |
  | **FastUnmarshalInt32Slice-6**    | 6377149  | 183.2 ns/op  | 112 B/op   | 1 allocs/op    |
  | StandardUnmarshalInt32Slice-6    | 3752682  | 318.7 ns/op  | 248 B/op   | 5 allocs/op    |
  | **FastUnmarshalSint64Slice-6**   | 4416526  | 271.5 ns/op  | 208 B/op   | 1 allocs/op    |
  | StandardUnmarshalSint64Slice-6   | 2903524  | 405.0 ns/op  | 504 B/op   | 6 allocs/op    |
  | **FastUnmarshalSfixed32Slice-6** | 14313001 | 85.07 ns/op  | 112 B/op   | 1 allocs/op    |
  | StandardUnmarshalSfixed32Slice-6 | 5353230  | 224.2 ns/op  | 248 B/op   | 5 allocs/op    |
  | **FastUnmarshalSfixed64Slice-6** | 12808696 | 103.0 ns/op  | 208 B/op   | 1 allocs/op    |
  | StandardUnmarshalSfixed64Slice-6 | 3824290  | 317.3 ns/op  | 504 B/op   | 6 allocs/op    |
  | **FastUnmarshalMixedProto-6**    | 20580    | 58110 ns/op  | 46909 B/op | 606 allocs/op  |
  | StandardUnmarshalMixedProto-6    | 8949     | 132525 ns/op | 60842 B/op | 1966 allocs/op |

Golang Go语言中推广支持proto3的protobuf生成工具,欢迎来找虫

更多关于Golang Go语言中推广支持proto3的protobuf生成工具,欢迎来找虫的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

7 回复

支持造轮子,但是我不用,我讨厌 protobuf 。

更多关于Golang Go语言中推广支持proto3的protobuf生成工具,欢迎来找虫的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是否支持 tinygo 下的编译,google 自己的大量使用了 reflect ,在 tinygo 下不能用。gogoprotobuf 的需要自己改动部分代码可以在 tinygo 下使用。

现在这个工具只是在 google 自己的.pb.go 文件之外,额外生成 marshal 、marshalto 、unmarshal 几个方法。结构的定义还是依赖于 google 的.pb.go 文件。

先去瞄一眼

我看了下,vtprotobuf 生成出来的代码和 gogoprotobuf 生成出来的代码一样的,而 fastproto 也是参考的 gogoprotobuf ,不过生成出来的代码重新成引用 google 的 protowire 这个包来读写数据。所以两者在性能上应该是一个量级的,不会有太大偏差
2. 两者有个区别就是 fastproto 支持自己的 message 里面引用其它人只用标准 proto 生成的 message ,比如 google 标准库里面的 Any 类型和 timestamp 类型。vtprotobuf 试了下不行。
3. Marshal 函数,gogoprotobuf 原来的实现是从后面往前写,fastproto 为了使用 protowire 这个库里面的标准函数,所以改成从前往后写。

在Golang中推广支持proto3的protobuf生成工具,无疑是一个提升开发效率和数据序列化性能的好举措。以下是我对protobuf在Golang中的使用及推广的一些看法和建议:

  1. 安装与配置:确保protoc编译器和protoc-gen-go插件已正确安装并配置到环境变量中。这样,我们就可以通过protoc命令轻松地将.proto文件编译成Go代码。
  2. 定义数据结构:使用.proto文件定义数据结构时,应遵循proto3的语法规则。定义消息类型、字段和枚举等,以清晰地描述需要序列化的数据。
  3. 生成Go代码:利用protoc编译器和–go_out选项,我们可以将.proto文件编译成对应的Go代码。这些代码包含了用于序列化和反序列化数据的结构体和方法。
  4. 测试与验证:在推广过程中,应充分测试protobuf的序列化和反序列化功能,以确保其正确性和稳定性。同时,也要关注protobuf的性能表现,以验证其是否满足项目的需求。
  5. 文档与社区支持:提供详细的文档和示例代码,帮助开发者快速上手。同时,积极参与社区讨论,解答开发者的问题,共同推动protobuf在Golang中的普及和应用。

希望这些建议能对你有所帮助,也期待protobuf在Golang中能够发挥更大的作用。

回到顶部