protobuf

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2023 License: MIT Imports: 13 Imported by: 0

README

Protobuf Parser

能力

  1. 基于 libprotobuf 3.19.0 解析 proto 文件,解决一些开源的Go的Protobuf解析库和官方的库不一致的问题!

  2. 支持的环境

  • Darwin amd64
  • Linux amd64

有其他环境需求可自行提交 MR,只要本地跑通单元测试即可!

使用

  1. 下载依赖
CGO_ENABLED=1 go get -v github.com/anthony-dong/protobuf
  1. 如何使用: main.go
package main

import (
	"fmt"

	"github.com/anthony-dong/protobuf"
)

func main() {
	tree, err := protobuf.NewProtobufDiskSourceTree("internal/test/idl_example")
	if err != nil {
		panic(err)
	}
	idlConfig := new(protobuf.IDLConfig)
	idlConfig.IDLs = tree
	idlConfig.Main = "service/im.proto"
	idlConfig.IncludePath = []string{"desc", "."}

	desc, err := protobuf.ParsePBMultiFileDesc(idlConfig,
		protobuf.WithJsonTag(),
		protobuf.WithSourceCodeInfo(),
		protobuf.WithGoogleProtobuf(),
		protobuf.WithRequireSyntaxIdentifier(),
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(protobuf.MessageToJson(desc, true))
}

// 运行: CGO_ENABLED=1 go run main.go

性能

压测文件

  1. 解析PB文件性能

    压测文件: cgo_test.go

go test -v -run=none -bench=Benchmark -memprofile mem.out  -benchmem  -count=5 .
goos: linux
goarch: amd64
pkg: github.com/anthony-dong/protobuf
cpu: Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz
Benchmark_cgo_parse_pb_pb
Benchmark_cgo_parse_pb_pb-8     	   29761	     40551 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_pb-8     	   28610	     41515 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_pb-8     	   29256	     41575 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_pb-8     	   29144	     41192 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_pb-8     	   30019	     40678 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_json
Benchmark_cgo_parse_pb_json-8   	    9913	    114188 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_json-8   	    9848	    114095 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_json-8   	    9326	    115046 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_json-8   	   10000	    116789 ns/op	      16 B/op	       1 allocs/op
Benchmark_cgo_parse_pb_json-8   	    9115	    117856 ns/op	      16 B/op	       1 allocs/op
PASS
ok  	github.com/anthony-dong/protobuf	13.772s
  1. 对比 github.com/jhump/protoreflect@v1.8.2 解析库

原因是我司用的是 v1.8.2 版本, 高版本兼容性检测会高一些!

压测文件:

goos: linux
goarch: amd64
pkg: github.com/anthony-dong/protobuf/internal/benchmark
cpu: Intel(R) Xeon(R) Platinum 8260 CPU @ 2.40GHz
Benchmark_ParsePBMultiFileDesc_Cgo
Benchmark_ParsePBMultiFileDesc_Cgo-8     	     942	   1207139 ns/op	   60937 B/op	    1976 allocs/op
Benchmark_ParsePBMultiFileDesc_Cgo-8     	     996	   1216023 ns/op	   60939 B/op	    1976 allocs/op
Benchmark_ParsePBMultiFileDesc_Cgo-8     	     958	   1223891 ns/op	   60936 B/op	    1976 allocs/op
Benchmark_ParsePBMultiFileDesc_Cgo-8     	     962	   1245004 ns/op	   60936 B/op	    1976 allocs/op
Benchmark_ParsePBMultiFileDesc_Cgo-8     	     986	   1225556 ns/op	   60936 B/op	    1976 allocs/op
Benchmark_ParsePBMultiFileDesc_Jhump
Benchmark_ParsePBMultiFileDesc_Jhump-8   	     508	   2404250 ns/op	  762870 B/op	   11038 allocs/op
Benchmark_ParsePBMultiFileDesc_Jhump-8   	     468	   2414933 ns/op	  762874 B/op	   11038 allocs/op
Benchmark_ParsePBMultiFileDesc_Jhump-8   	     494	   2404417 ns/op	  762828 B/op	   11038 allocs/op
Benchmark_ParsePBMultiFileDesc_Jhump-8   	     498	   2343901 ns/op	  762930 B/op	   11038 allocs/op
Benchmark_ParsePBMultiFileDesc_Jhump-8   	     494	   2412528 ns/op	  762977 B/op	   11038 allocs/op
Benchmark_ParsePBFileDesc_Cgo
Benchmark_ParsePBFileDesc_Cgo-8          	   22116	     54090 ns/op	    5024 B/op	     145 allocs/op
Benchmark_ParsePBFileDesc_Cgo-8          	   22134	     54031 ns/op	    5024 B/op	     145 allocs/op
Benchmark_ParsePBFileDesc_Cgo-8          	   21500	     56155 ns/op	    5024 B/op	     145 allocs/op
Benchmark_ParsePBFileDesc_Cgo-8          	   20539	     57158 ns/op	    5024 B/op	     145 allocs/op
Benchmark_ParsePBFileDesc_Cgo-8          	   21400	     55135 ns/op	    5024 B/op	     145 allocs/op
Benchmark_ParsePBFileDesc_Jhump
Benchmark_ParsePBFileDesc_Jhump-8        	    3837	    307914 ns/op	  107032 B/op	    1735 allocs/op
Benchmark_ParsePBFileDesc_Jhump-8        	    3874	    311001 ns/op	  107036 B/op	    1735 allocs/op
Benchmark_ParsePBFileDesc_Jhump-8        	    3578	    319180 ns/op	  107037 B/op	    1735 allocs/op
Benchmark_ParsePBFileDesc_Jhump-8        	    3895	    308775 ns/op	  107035 B/op	    1735 allocs/op
Benchmark_ParsePBFileDesc_Jhump-8        	    3873	    313726 ns/op	  107033 B/op	    1735 allocs/op
PASS
ok  	github.com/anthony-dong/protobuf/internal/benchmark	28.682s
  1. 结论:
  • 解析单文件实际上由于C++极致的性能,也就是说冗余了一次序列化+反序列化,性能也能是5-6倍!
  • 解析多文件由于大量的时间浪费在序列化和反序列化上,导致性能裂化较为严重,性能只能到2倍左右!
  • 其次就是内存压力的大大降低!

Todo

  • Go 官方的 Protobuf 序列化库实际上是用的反射去实现的,可以通过代码生成工具实现硬编码解析,性能会再提高很多!
  • 寻找更多的突破口,降低序列化和反序列化的开销,例如直接做C++ -> Go的数据绑定, 这个可能代码工作量会大一些,但是可以避免无效的序列化,这个我争取在下个版本release了!
  • CGO中存在大量的数据转换,是不是有一些代码生成辅助工具帮忙实现呢?但是GO和C其实还好,但是GO与C++就比较恶心了,需要保存一个void*指针去做中转,因为C++基本上不可能只有POD类型,大多数都是复杂类型!

Documentation

Index

Constants

View Source
const (
	MessageType_PB = iota
	MessageType_JSON
)

Variables

This section is empty.

Functions

func MessageToJson

func MessageToJson(v proto.Message, pretty ...bool) string

func NewDiskSourceTree added in v1.0.2

func NewDiskSourceTree(dir string, filter func(filename string) bool) (map[string][]byte, error)

func NewProtobufDiskSourceTree added in v1.0.2

func NewProtobufDiskSourceTree(dir string) (map[string][]byte, error)

func ParsePBFileDesc

func ParsePBFileDesc(file []byte, ops ...OptionFunc) (*descriptor.FileDescriptorProto, error)

func ParsePBMultiFileDesc added in v1.0.2

func ParsePBMultiFileDesc(idl *IDLConfig, ops ...OptionFunc) (*descriptor.FileDescriptorSet, error)

func UnsafeBytes

func UnsafeBytes(str string) []byte

func UnsafeString added in v1.0.2

func UnsafeString(bytes []byte) string

Types

type ErrorMessage

type ErrorMessage struct {
	Filename string
	Line     int
	Column   int
	Message  string
}

type ErrorMessages

type ErrorMessages []*ErrorMessage

func (ErrorMessages) Error

func (e ErrorMessages) Error() string

type IDLConfig added in v1.0.2

type IDLConfig struct {
	Main        string
	IDLs        map[string][]byte
	IncludePath []string
}

type MessageType

type MessageType int

type Option

type Option struct {
	MessageType             MessageType
	RequireSyntaxIdentifier bool
	WithSourceCodeInfo      bool
	WithJsonTag             bool
	WithGoogleProtobuf      bool
}

func LoadOptions added in v1.0.2

func LoadOptions(ops ...OptionFunc) *Option

type OptionFunc

type OptionFunc func(*Option)

func WithGoogleProtobuf added in v1.0.2

func WithGoogleProtobuf() OptionFunc

func WithJsonTag added in v1.0.2

func WithJsonTag() OptionFunc

func WithMessageType

func WithMessageType(t MessageType) OptionFunc

func WithRequireSyntaxIdentifier

func WithRequireSyntaxIdentifier() OptionFunc

func WithSourceCodeInfo added in v1.0.2

func WithSourceCodeInfo() OptionFunc

Directories

Path Synopsis
deps
darwin_x86_64
Package darwin_x86_64 is required to provide support for vendoring modules DO NOT REMOVE
Package darwin_x86_64 is required to provide support for vendoring modules DO NOT REMOVE
linux_x86_64
Package linux_x86_64 is required to provide support for vendoring modules DO NOT REMOVE
Package linux_x86_64 is required to provide support for vendoring modules DO NOT REMOVE
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL