Перейти двоичный вариант кодирования против фиксированной длины слайса - PullRequest
0 голосов
/ 28 ноября 2018

Мне нужно закодировать целочисленные ключи как байтовые фрагменты для базы данных 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 голосов
/ 28 ноября 2018

Двоичный пакет

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...