ZhangZhihui's Blog  

 

package main

import (
    "fmt"
    "log"
    "unsafe"

    "golang.org/x/exp/constraints"
    "google.golang.org/protobuf/proto"
    "google.golang.org/protobuf/reflect/protoreflect"
    "google.golang.org/protobuf/types/known/wrapperspb"
)


// PrintStrBin converts a string to binary format and print it byte by byte.
func PrintStrBin(str string) {
    fmt.Println(str)
    fmt.Println([]byte(str))
    fmt.Println()

    var s string
    length := 0
    for _, c := range []byte(str) {
        cBin := fmt.Sprintf("%08b", c)
        fmt.Println(cBin)
        s = s + cBin
        length = length + len(cBin)
    }

    fmt.Println()
}

// ProtoSerializedSize returns the size of an integer in memory and the size of 
// the same integer being serialized with Protobuf
func ProtoSerializedSize[D constraints.Integer, W protoreflect.ProtoMessage] (data D, wrapper W) (uintptr, int) {
    out, err := proto.Marshal(wrapper)

    if err != nil {
        log.Fatal(err)
    }

    return unsafe.Sizeof(data), len(out) - 1
    // You might be thinking that the –1 after len(out) is cheating.
    // With Protobuf, Int32Value is serialized into 6 bytes. While you are right about the fact
    // that the real serialization size is 6 bytes, the first bytes represent the type and field tag. 
    // So, to keep the comparison of the serialized data fair,
    // we remove the metadata and only compare the number itself.
}

 

ProtoSerializedSize:

func main() {
    var data int32 = 268_435_456
    i32 := &wrapperspb.Int32Value{
        Value: data,
    }

    d, w := ProtoSerializedSize(data, i32)

    fmt.Printf("in memory: %d\npb: %d\n", d, w)
}

 

zzh@ZZHPC:/zdata/Github/ztest$ go run util.go
in memory: 4
pb: 5

 

posted on 2024-04-11 07:30  ZhangZhihuiAAA  阅读(3)  评论(0编辑  收藏  举报