首页 > 解决方案 > 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返回写入的字节数,所以我可以拼接字节切片。

这是正确的方法吗?如果不是,使切片更小的正确方法是什么?

谢谢

标签: go

解决方案


包二进制

import "encoding/binary"

func PutUvarint

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

推荐阅读