去二进制编码变体与固定切片长度

时间:2018-11-28 01:53:22

标签: 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))

}

我的问题是。我是否必须使用变体编码手动拼接字节切片以摆脱多余的字节? 由于put PutUvariant返回写入的字节数,因此我可以拼接字节片。

这是正确的方法吗? 如果没有,缩小切片的正确方法是什么?

谢谢

1 个答案:

答案 0 :(得分:1)

  

Package binary

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