go - Go 二进制编码变体与固定切片长度
问题描述
我需要将整数键编码为 KV 数据库的字节片。我想使编码更小并减少零填充。我认为二进制包中的变体编码将是可行的方法。
但在两种情况下,变体和固定,字节切片长度是相同的。由于第一位用作标志,因此只是不同的位排列。我认为变体编码会减少“额外的脂肪”。不。
package main
import (
"encoding/binary"
"fmt"
)
func main() {
x := 16
y := 106547
fmt.Println(x)
fmt.Println(y)
// Variant
bvx := make([]byte, 8)
bvy := make([]byte, 8)
xbts := binary.PutUvarint(bvx, uint64(x))
ybts := binary.PutUvarint(bvy, uint64(y))
fmt.Println("Variant bytes written x: ", xbts)
fmt.Println("Variant bytes written y: ", ybts)
fmt.Println(bvx)
fmt.Println(bvy)
fmt.Println("bvx length: ", len(bvx))
fmt.Println("bvy length: ", len(bvy))
// Fixed
bfx := make([]byte, 8)
bfy := make([]byte, 8)
binary.LittleEndian.PutUint64(bfx, uint64(x))
binary.LittleEndian.PutUint64(bfy, uint64(y))
fmt.Println(bfx)
fmt.Println(bfy)
fmt.Println("bfx length: ", len(bfx))
fmt.Println("bfy length: ", len(bfy))
}
我的问题是。我是否必须使用变体编码手动拼接字节切片以消除额外的字节?由于 putPutUvariant
返回写入的字节数,所以我可以拼接字节切片。
这是正确的方法吗?如果不是,使切片更小的正确方法是什么?
谢谢
解决方案
import "encoding/binary"
func PutUvarint(buf []byte, x uint64) int
PutUvarint 将 uint64 编码为 buf 并返回写入的字节数。如果缓冲区太小,PutUvarint 会恐慌。
修复您的代码:
bvx := make([]byte, binary.MaxVarintLen64)
bvy := make([]byte, binary.MaxVarintLen64)
bvx = bvx[:binary.PutUvarint(bvx[:cap(bvx)], uint64(x))]
bvy = bvy[:binary.PutUvarint(bvy[:cap(bvy)], uint64(y))]
package main
import (
"encoding/binary"
"fmt"
)
func main() {
x := 16
y := 106547
fmt.Println(x)
fmt.Println(y)
// Variant
bvx := make([]byte, binary.MaxVarintLen64)
bvy := make([]byte, binary.MaxVarintLen64)
bvx = bvx[:binary.PutUvarint(bvx[:cap(bvx)], uint64(x))]
bvy = bvy[:binary.PutUvarint(bvy[:cap(bvy)], uint64(y))]
fmt.Println("Variant bytes written x: ", len(bvx))
fmt.Println("Variant bytes written y: ", len(bvy))
fmt.Println(bvx)
fmt.Println(bvy)
fmt.Println("bvx length: ", len(bvx))
fmt.Println("bvy length: ", len(bvy))
// Fixed
bfx := make([]byte, 8)
bfy := make([]byte, 8)
binary.LittleEndian.PutUint64(bfx, uint64(x))
binary.LittleEndian.PutUint64(bfy, uint64(y))
fmt.Println(bfx)
fmt.Println(bfy)
fmt.Println("bfx length: ", len(bfx))
fmt.Println("bfy length: ", len(bfy))
}
游乐场: https: //play.golang.org/p/XN46KafMY23
输出:
16
106547
Variant bytes written x: 1
Variant bytes written y: 3
[16]
[179 192 6]
bvx length: 1
bvy length: 3
[16 0 0 0 0 0 0 0]
[51 160 1 0 0 0 0 0]
bfx length: 8
bfy length: 8
推荐阅读
- visual-studio - 如何在解决方案资源管理器中切换视图?
- match - pythonforandroid(p4a)中blacklist.txt的用途是什么?
- r - 如何在 R 中的 PDF 输出中显示所有变量?
- java - 使用标签在 HTML 和 Angular 中打开弹出窗口
- css - 当 Vuetify 导航栏应该保持静态时,它会随着列表一起增长和滚动
- ios - 应用未运行时从“设置”中关闭定位服务时提示用户
- c - 如何使用 FMOD 在 C 代码中播放 MP3 文件?
- apache - 如何强制 Heroku PHP 应用使用 SSL 证书(https)?
- firebase - Flutter:向用户显示总分/等级
- c++ - 将选项传递给编译器,但不传递给 cmake 中的链接器