V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
ybilly
V2EX  ›  Go 编程语言

推广一下支持 proto3 的 protobuf 生成工具,欢迎来找虫

  •  
  •   ybilly · 329 天前 · 1158 次点击
    这是一个创建于 329 天前的主题,其中的信息可能已经有所发展或是发生改变。

    失业在家,把原来用到的 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 |
    
    6 条回复    2023-05-27 17:54:56 +08:00
    FrankAdler
        1
    FrankAdler  
       329 天前
    支持造轮子,但是我不用,我讨厌 protobuf 。
    millken
        2
    millken  
       329 天前
    是否支持 tinygo 下的编译,google 自己的大量使用了 reflect ,在 tinygo 下不能用。gogoprotobuf 的需要自己改动部分代码可以在 tinygo 下使用。
    ybilly
        3
    ybilly  
    OP
       329 天前
    @millken 现在这个工具只是在 google 自己的.pb.go 文件之外,额外生成 marshal 、marshalto 、unmarshal 几个方法。结构的定义还是依赖于 google 的.pb.go 文件。
    mcfog
        4
    mcfog  
       328 天前
    ybilly
        5
    ybilly  
    OP
       328 天前
    @mcfog 先去瞄一眼
    ybilly
        6
    ybilly  
    OP
       327 天前
    @mcfog 我看了下,vtprotobuf 生成出来的代码和 gogoprotobuf 生成出来的代码一样的,而 fastproto 也是参考的 gogoprotobuf ,不过生成出来的代码重新成引用 google 的 protowire 这个包来读写数据。所以两者在性能上应该是一个量级的,不会有太大偏差
    2. 两者有个区别就是 fastproto 支持自己的 message 里面引用其它人只用标准 proto 生成的 message ,比如 google 标准库里面的 Any 类型和 timestamp 类型。vtprotobuf 试了下不行。
    3. Marshal 函数,gogoprotobuf 原来的实现是从后面往前写,fastproto 为了使用 protowire 这个库里面的标准函数,所以改成从前往后写。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5687 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 02:31 · PVG 10:31 · LAX 19:31 · JFK 22:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.