要让数据对象能在网络上传输或存储,我们需要进行编码和解码。现在比较流行的编码方式有JSON,XML等。然而,Go在gob包中为我们提供了另一种方式,该方式编解码效率高于JSON。gob是Golang包自带的一个数据结构序列化的编码/解码工具

源和目的地值/类型不需要完全对应。在接收变量中,但从发送类型或值丢失的字段将在目标中被忽略。如果在两个字段中都存在同名的字段,则它们的类型必须兼容。接收器和发送器都会做所有必要的间接和迂回,以在实际值和实际值之间转换。

struct { A, B int }
can be sent from or received into any of these Go types:

struct { A, B int } // the same
*struct { A, B int } // extra indirection of the struct
struct { *A, **B int } // extra indirection of the fields
struct { A, B int64 } // different concrete value type; see below
It may also be received into any of these:

struct { A, B int } // the same
struct { B, A int } // ordering doesn't matter; matching is by name
struct { A, B, C int } // extra field (C) ignored
struct { B int } // missing field (A) ignored; data will be dropped
struct { B, C int } // missing field (A) ignored; extra field (C) ignored.
Attempting to receive into these types will draw a decode error:

struct { A int; B uint } // change of signedness for B
struct { A int; B float } // change of type for B
struct { } // no field names in common
struct { C, D int } // no field names in common
例子:

package main

import (
"bytes"
"encoding/gob"
"fmt"
)

type Person struct {
Name string
Age int
Action Run
}

type Run struct {
Speed int
}

func main() {
var dao bytes.Buffer

var encoder = gob.NewEncoder(&dao)
var decoder = gob.NewDecoder(&dao)

p := Person{Name:"chen",Age:18,Action:Run{80}}

err := encoder.Encode(&p)
if err != nil{
panic(err)
}

fmt.Println(dao.String())

var d Person
err = decoder.Decode(&d)
if err != nil{
panic(err)
}

fmt.Println(d)
}
如果Encode/Decode类型是interface或者struct中某些字段是interface{}的时候,需要在gob中注册interface可能的所有实现或者可能类型,不然会报:panic: gob: type not registered for interface: main.Run错误

例子2 编解码的struct中某些字段是interface{}的时候

package main

import (
"encoding/gob"
"fmt"
"bytes"
)

func init() {
gob.Register(&Run{})//必须在encoding/gob编码解码前进行注册
}

//panic: gob: type not registered for interface: main.Run
type Person struct {
Name string
Age int
Action interface{}
}

type Run struct {
Speed int
}

func main() {
var dao bytes.Buffer

encoder := gob.NewEncoder(&dao)
decoder := gob.NewDecoder(&dao)

p := Person{Name:"chen",Age:18,Action:Run{80}}

err := encoder.Encode(&p)
if err != nil{
panic(err)
}

fmt.Println(dao.String())

var d Person
err = decoder.Decode(&d)
if err != nil{
panic(err)
}

fmt.Println(d)

}
例子3 编解码的类型是interface

package main

import (
"fmt"
"bytes"
"encoding/gob"
)

func init() {
gob.Register(&Person{})//必须在encoding/gob编码解码前进行注册
gob.Register(&Dog{})
}

type Actioner interface {
Action()
}

type Person struct {
Name string
}

type Dog struct {
Name string
}

func (p *Person)Action() {
fmt.Println("person action")
}

func (p *Dog)Action() {
fmt.Println("dog action")
}

func main() {
var dao bytes.Buffer

encoder := gob.NewEncoder(&dao)
decoder := gob.NewDecoder(&dao)

var action Actioner
action = &Person{"chen"}
err := encoder.Encode(&action)
if err != nil{
panic(err)
}
action = &Dog{"jok"}
err = encoder.Encode(&action)
if err != nil{
panic(err)
}

err = decoder.Decode(&action)
if err != nil{
panic(err)
}
fmt.Println(action)
action.Action()

err = decoder.Decode(&action)
if err != nil{
panic(err)
}

fmt.Println(action)
action.Action()
}
我们也可以将*bytes.Buffer换成*os.File,将编码后的对象写入磁盘存储

性能测试

下面进行一下简单的性能测试,测试一下gob和json的编解码性能。

gob:

package main

import (
"bytes"
"encoding/gob"
"fmt"
"time"
)

type Person struct {
Name string
Age int
Action Run
}

type Run struct {
Speed int
}
var dao bytes.Buffer

var encoder = gob.NewEncoder(&dao)
var decoder = gob.NewDecoder(&dao)

func Gob() {

p := Person{Name:"chen",Age:18,Action:Run{80}}

err := encoder.Encode(&p)
if err != nil{
panic(err)
}

//fmt.Println(dao.String())

var d Person
err = decoder.Decode(&d)
if err != nil{
panic(err)
}

//fmt.Println(d)
}

func main() {
now := time.Now()
start := now.UnixNano()
for i := 0; i < 10000; i++ {
Gob()
}
now2 := time.Now()
end := now2.UnixNano()
fmt.Println(end - start) //25016400
}
gob编解码循环10000次所需时间为25016400纳秒

json:

package main

import (
"encoding/json"
"fmt"
"time"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Action Run `json:"action"`
}

type Run struct {
Speed int `json:"speed"`
}

func Json() {
p := Person{Name:"chen",Age:18,Action:Run{80}}

data,err := json.Marshal(p)
if err != nil{
panic(err)
}

//fmt.Println(string(data))

var d Person
err = json.Unmarshal(data,&d)
if err != nil{
panic(err)
}

//fmt.Println(d)
}

func main() {
now := time.Now()
start := now.UnixNano()
for i := 0; i < 10000; i++ {
Json()
}
now2 := time.Now()
end := now2.UnixNano()
fmt.Println(end - start) //45037200
}
json编解码循环10000次所需时间为45037200纳秒

总结:粗略的测试gob的性能大概是json的两倍左右

转: gob编解码的更多相关文章

  1. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  2. 集显也能硬件编码:Intel SDK && 各种音视频编解码学习详解

    http://blog.sina.com.cn/s/blog_4155bb1d0100soq9.html INTEL MEDIA SDK是INTEL推出的基于其内建显示核心的编解码技术,我们在播放高清 ...

  3. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  4. 【miscellaneous】各种音视频编解码学习详解

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  5. 【FFMPEG】各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    目录(?)[-] 编解码学习笔记二codec类型 编解码学习笔记三Mpeg系列Mpeg 1和Mpeg 2 编解码学习笔记四Mpeg系列Mpeg 4 编解码学习笔记五Mpeg系列AAC音频 编解码学习笔 ...

  6. iOS8系统H264视频硬件编解码说明

    公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...

  7. IOS和Android支持的音频编解码

    1.IOS编码 参考文档地址:https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/Multimedi ...

  8. java编解码技术,netty nio

    对于java提供的对象输入输出流ObjectInputStream与ObjectOutputStream,可以直接把java对象作为可存储 的字节数组写入文件,也可以传输到网络上去.对与java开放人 ...

  9. 编解码-marshalling

    JBoss的Marshalling序列化框架,它是JBoss内部使用的序列化框架,Netty提供了Marshalling编码和解码器,方便用户在Netty中使用Marshalling. JBoss M ...

随机推荐

  1. 【51nod】1742 开心的小Q

    题解 我们由于莫比乌斯函数如果有平方数因子就是0,那么我们可以列出这样的式子 \(\sum_{i = 1}^{n} \sum_{d|i} (1 - |\mu(d)|)\) 然后枚举倍数 \(\sum_ ...

  2. 【LOJ】#2446. 「NOI2011」 NOI 嘉年华

    题解 一道神奇的dp 我们发现关于两个东西的记录很难办,但是我们发现在固定时间区间内,如果A场地举办的活动数是一定的,那么B场地肯定举办的活动越多越好 我们预处理一个\(num[i][j]\)表示时间 ...

  3. FILE operattion

    #include "mainwindow.h"#include "ui_mainwindow.h"#include <QMessageBox>#in ...

  4. 学习 HMM

    简介 HMM 中的变量可以分为两组. 第一组是状态变量 \(\{y_i,y_2,\cdots, y_n\}\), 其中 \(y_i \in \mathcal{Y}\) 表示第 \(i\) 时刻的系统状 ...

  5. TCP流嗅探和连接跟踪工具tcpick

    TCP流嗅探和连接跟踪工具tcpick   由于网络通信协议众多,TCP连接状态众多,所以TCP分析较为复杂.Kali Linux提供一款专用工具tcpick.该工具支持在线实时嗅探和离线文件嗅探.它 ...

  6. Xamarin 2017.10.9更新

     Xamarin 2017.10.9更新 本次更新主要解决了一些bug.Visual Studio 2017升级到15.4获得新功能.Visual Studio 2015需要工具-选项-Xamarin ...

  7. [BZOJ4565][HAOI2016]字符合并(区间状压DP)

    https://blog.csdn.net/xyz32768/article/details/81591955 首先区间DP和状压DP是比较明显的,设f[L][R][S]为将[L,R]这一段独立操作最 ...

  8. 友好的KVO

    更友好的KVO 前言 观察者模式是大家在开发过程中每个人都要使用的一种设计模式,在iOS的开发流程中,KVO则是这一开发模式的主要实践手段,观察一个属性,当属性值发生变化的就能能够拿到这个属性的新.老 ...

  9. 转 MySQL连接超时

    在负载较重的MySQL服务器上,有时你偶尔会看到一些连接超时的错误,诸如: Can’t connect to MySQL server on ‘mydb’(110).如果当时你有多个连接请求,你会发现 ...

  10. 每一个JavaScript开发者应该了解的浮点知识

    在JavaScript开发者的开发生涯中的某些点,总会遇到奇怪的BUG——看似基础的数学问题,但却又觉得有些不对劲.总有一天,你会被告知JavaScript中的数字实际上是浮点数.试图了解浮点数和为什 ...