高效的二进制编码结构体

huangapple go评论84阅读模式
英文:

Efficient binary encoding of struct

问题

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

type packet struct {
    dataLength uint16
    id [8]byte
    pairity, shards, flags byte
    blob []byte // 长度由dataLength定义
}

我使用encoding/binary包进行序列化/反序列化,但效率不够高(使用了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操作)?

英文:

I have a program that sends udp packets.
a packet datagram is represented by the following struct (notice that the size of the packet isn't fixed):

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

I used encoding/binary package to do serialization/deserialization but it wasn't efficient enough (used pprof). it wasted alot of CPU time and I couldn't utilize the whole network speed because of that.

for example, consider the following code:

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()

What is the most efficient way to do this operation (and also the .FromBytes operation)

答案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
}

这个函数手动构建了缓冲区,效率比使用 encoding/binary.Write 更高。

英文:

encoding/binary.Write uses reflection, so it will be slower than anything that manually constructs the buffer. Below is an example of such a function:

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
}

huangapple
  • 本文由 发表于 2016年3月26日 03:29:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/36226638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定