go语言内置了gob这种编码方案,我从来没用过,感觉很好奇,今天试试。
先写一个简单的代码体验一下:
type Retangle struct {
Length uint8
Width uint8
}
func main() {
r := Retangle{
20,
18,
}
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
err := encoder.Encode(&r)
if err != nil {
fmt.Printf("encode err:%v", err)
return
}
data := buffer.Bytes()
fmt.Printf("编码后的数据: %x,数据长度:%d\n", data, len(data))
//传输.......
var otherR Retangle
decoder := gob.NewDecoder(bytes.NewReader(data))
err = decoder.Decode(&otherR)
if err != nil {
fmt.Printf("decode err:%v", err)
return
}
fmt.Printf("解码数据: %v\n", otherR)
}
运行结果如下:
编码后的数据: 2bff8103010108526574616e676c6501ff8200010201064c656e67746801060001055769647468010600000007ff820114011200,数据长度:52
解码数据: {20 18}
看到这里,我心里只想说一句WTF。
一个2字节长的结构体被编码成52字节长的数据,想吐血。
暂时忍一下,看看长一点的数据效果会不会有改善,我把编解码的数据类型由结构体改成结构体slice类型。代码如下:
type Retangle struct {
Length uint8
Width uint8
}
func main() {
r := Retangle{
20,
18,
}
var rects []Retangle
for i:=0; i<100;i++ {
rects = append(rects, r)
}
var buffer bytes.Buffer
encoder := gob.NewEncoder(&buffer)
err := encoder.Encode(&rects)
if err != nil {
fmt.Printf("encode err:%v", err)
return
}
data := buffer.Bytes()
fmt.Printf("编码后的数据: %x,数据长度:%d\n", data, len(data))
//传输.......
var otherRs []Retangle
decoder := gob.NewDecoder(bytes.NewReader(data))
err = decoder.Decode(&otherRs)
if err != nil {
fmt.Printf("decode err:%v", err)
return
}
fmt.Printf("解码数据: %v\n", otherRs)
}
运行的效果是,编码后的数据长度达到:565字节。晕死,200字节长的数据编码后变成565字节了,这膨胀得有点严重啊。
接着我把要编码的slice长度提升到1000,运行效果是编码后的数据长度达到5067。
最后再把要编码的slice长度提升到10000,运行效果是编码后的数据长度达到50067。
看来很稳定啊,膨胀到2.5倍啊。内心真是有句MMP不知道当讲不当讲。
(全文完)