golang高性能零分配原生类型字节打包插件库bingo的使用
Golang高性能零分配原生类型字节打包插件库bingo的使用
特性
- 支持编码
bool
、string
、int8
、int16
、int32
、int64
、uint8
、uint16
、uint32
、uint64
、float32
、float64
和time.Time
类型 - 打包后的值保持原始排序顺序
- 支持按降序打包值
- 可以将值打包到现有的字节切片中,无需额外分配
- 创建并打包值到新的字节切片(一次分配)
- 可以解包所有值或仅解包特定索引的值
使用示例
首先导入bingo库:
import "github.com/iancmcc/bingo"
基本打包和解包
// 创建并返回包含编码值的字节切片
key := bingo.MustPack(uint8(12), "cool string bro")
// 解包
var (
first uint8
second string
)
bingo.Unpack(key, &first, &second)
降序打包和部分解包
// 打包时让第二个值按降序排序
key = bingo.WithDesc(false, true, false).MustPack(1, time.Now(), true)
// 只解包中间的值
var t time.Time
bingo.UnpackIndex(key, 1, &t)
打包到现有切片
// 打包到现有的字节切片
existingSlice := make([]byte, 100)
bingo.MustPackTo(existingSlice, uint16(7), "abc123")
性能基准测试
以下是bingo库的性能基准测试结果:
goos: linux
goarch: amd64
pkg: github.com/iancmcc/bingo
cpu: Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
BenchmarkCodecs/int8/encode/natural-8 100000000 10.35 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int8/encode/inverse-8 89794872 12.60 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int8/decode/natural-8 65864187 17.11 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int8/decode/inverse-8 63386660 17.27 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int16/encode/natural-8 100000000 10.04 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int16/encode/inverse-8 85618111 13.08 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int16/decode/natural-8 64825372 16.55 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int16/decode/inverse-8 58359490 19.44 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int32/encode/natural-8 120393369 9.942 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int32/encode/inverse-8 80418766 13.67 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int32/decode/natural-8 53423986 21.03 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int32/decode/inverse-8 47975257 24.68 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int64/encode/natural-8 100000000 10.95 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int64/encode/inverse-8 67093402 17.79 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int64/decode/natural-8 47149765 23.97 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/int64/decode/inverse-8 39063907 27.36 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float32/encode/natural-8 100000000 10.42 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float32/encode/inverse-8 79910834 14.11 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float32/decode/natural-8 63494347 16.88 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float32/decode/inverse-8 46677241 25.55 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float64/encode/natural-8 100000000 11.05 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float64/encode/inverse-8 62377978 17.48 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float64/decode/natural-8 62370994 17.26 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/float64/decode/inverse-8 54139144 20.68 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/string/encode/natural-8 47404435 23.80 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/string/encode/inverse-8 29144544 39.74 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/string/decode/natural-8 39683684 31.39 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/string/decode/inverse-8 23373333 48.06 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/time/encode/natural-8 47027752 24.72 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/time/encode/inverse-8 38363001 29.22 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/time/decode/natural-8 42566337 26.76 ns/op 0 B/op 0 allocs/op
BenchmarkCodecs/time/decode/inverse-8 30851250 36.88 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/iancmcc/bingo 37.644s
从基准测试结果可以看出,bingo库在各种数据类型的编码和解码操作上都表现出色,且实现了零内存分配。
更多关于golang高性能零分配原生类型字节打包插件库bingo的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang高性能零分配原生类型字节打包插件库bingo的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Bingo - Golang高性能零分配字节打包库使用指南
Bingo是一个专注于高性能、零内存分配的Golang原生类型字节打包/解包库,特别适合对性能要求苛刻的场景。下面我将详细介绍其核心功能和使用方法。
主要特性
- 零内存分配:通过预分配缓冲区和复用技术避免运行时内存分配
- 高性能:直接操作字节,避免反射开销
- 原生类型支持:支持所有Golang基本类型及常见复合类型
- 简单API:提供直观易用的编码/解码接口
安装
go get github.com/shenghui0779/bingo
基本使用
1. 基本类型编码/解码
package main
import (
"fmt"
"github.com/shenghui0779/bingo"
)
func main() {
// 创建编码器
enc := bingo.NewEncoder()
// 编码基本类型
enc.Bool(true)
enc.Int(-123)
enc.Uint(456)
enc.Float32(3.14)
enc.String("hello")
// 获取编码后的字节
data := enc.Bytes()
// 创建解码器
dec := bingo.NewDecoder(data)
// 解码
b := dec.Bool()
i := dec.Int()
u := dec.Uint()
f := dec.Float32()
s := dec.String()
fmt.Println(b, i, u, f, s) // 输出: true -123 456 3.14 hello
}
2. 结构体编码/解码
type Person struct {
Name string
Age int
Male bool
}
func main() {
p := Person{
Name: "Alice",
Age: 25,
Male: false,
}
// 编码结构体
enc := bingo.NewEncoder()
enc.String(p.Name)
enc.Int(p.Age)
enc.Bool(p.Male)
data := enc.Bytes()
// 解码结构体
dec := bingo.NewDecoder(data)
var p2 Person
p2.Name = dec.String()
p2.Age = dec.Int()
p2.Male = dec.Bool()
fmt.Printf("%+v\n", p2) // 输出: {Name:Alice Age:25 Male:false}
}
高级用法
1. 预分配缓冲区
func main() {
// 预分配1KB缓冲区
buf := make([]byte, 0, 1024)
enc := bingo.NewEncoderWithBuffer(buf)
// 编码大量数据
for i := 0; i < 100; i++ {
enc.Int(i)
}
data := enc.Bytes()
fmt.Println("编码后长度:", len(data))
}
2. 切片和数组处理
func main() {
// 编码切片
nums := []int{1, 2, 3, 4, 5}
enc := bingo.NewEncoder()
enc.Int(len(nums)) // 先写入长度
for _, n := range nums {
enc.Int(n)
}
data := enc.Bytes()
// 解码切片
dec := bingo.NewDecoder(data)
length := dec.Int()
nums2 := make([]int, length)
for i := 0; i < length; i++ {
nums2[i] = dec.Int()
}
fmt.Println(nums2) // 输出: [1 2 3 4 5]
}
3. 自定义类型编码
type Point struct {
X, Y float64
}
func (p *Point) Encode(enc *bingo.Encoder) {
enc.Float64(p.X)
enc.Float64(p.Y)
}
func (p *Point) Decode(dec *bingo.Decoder) {
p.X = dec.Float64()
p.Y = dec.Float64()
}
func main() {
p := Point{X: 1.5, Y: 2.5}
enc := bingo.NewEncoder()
p.Encode(enc)
data := enc.Bytes()
var p2 Point
dec := bingo.NewDecoder(data)
p2.Decode(dec)
fmt.Printf("%+v\n", p2) // 输出: {X:1.5 Y:2.5}
}
性能优化建议
- 复用编码器/解码器:对于频繁调用的场景,可以复用编码器/解码器对象
- 预估缓冲区大小:预先估计数据大小并分配足够缓冲区
- 批量处理:尽可能批量编码/解码数据
- 避免小对象频繁编码:对小对象考虑组合后再编码
注意事项
- 编码和解码顺序必须完全一致
- 解码时需确保有足够的数据可供读取,否则会panic
- 对于可变长度数据(如字符串、切片),通常需要先编码长度
Bingo通过直接操作字节和避免内存分配,在性能上比标准库的encoding/json等有显著优势,特别适合网络通信、高性能存储等场景。