高效的二进制编码结构体

3

我有一个可以发送UDP数据包的程序。 数据报由以下结构体表示(注意数据包大小不是固定的):

type packet struct {
    dataLength uint16
    id [8]byte
    pairity, shards, flags byte
    blob []byte // length defined by dataLength 
}

我使用了编码/二进制包来进行序列化和反序列化,但效率不够高(使用pprof进行分析)。由于这个原因,它浪费了大量CPU时间,我无法充分利用整个网络速度。
例如,请考虑以下代码:
packet := packet{
    dataLength: 4,
    id: [8]byte{1,2,3,4,5,6,7,8},
    pairity: 10,
    shards: 50,
    flags: 200,
    blob: []byte{1,2,3,4},
}
bufToSendOverNetwork := packet.ToBytes()

这个操作的最有效方式是什么(同时也是 .FromBytes 操作的最有效方式)?

你能展示一下你目前正在使用的二进制编码以及瓶颈在哪里吗?由于“blob”是一个切片,因此你的Go结构体并不能直接写入以匹配数据包结构体。 - JimB
1个回答

4

encoding/binary.Write 使用反射,因此它比手动构建缓冲区的任何方法都要慢。下面是一个这样的函数示例:

import (
    "encoding/binary"
)

func (p *packet) ToBytes() []byte {
    buff := make([]byte, 2 + 8 + 3 + len(p.blob))

    binary.BigEndian.PutUint16(buff[:2], p.dataLength)
    copy(buff[2:10], p.id[:])
    buff[10] = p.pairity
    buff[11] = p.shards
    buff[12] = p.flags
    copy(buff[13:], p.blob)

    return buff
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接