golang msgp

msgp简介

msgp是MessagePack的缩写,是一种高效的二进制序列化格式,用它官网的一句简单的介绍就是:"It's like JSON.but fast and small.",JSON大家都知道吧,基本JSON能做的事,msgp都能做,而且比JSON更快,更小。 官网在这,大家想详细了解的直接移步到官网去围观吧。

msgp应用在golang

既然msgp这么好,那支持的语言肯定很多吧,没错,到目前为止,msgp对大部分主流的语言都已经支持得很好了,包括golang,官方推荐的库在git上的地址https://github.com/tinylib/msgp 安装就直接go get就行

go get -u -t github.com/tinylib/msgp

这样msgp就直接安装到了golang环境中的工具库中。
由于msgp的原理是将字符序列化为二进制格式,因此需要一些转换代码来辅助序列化,当然这些代码并不用我们手动编写,而是由msgp工具生成,结合go1.4以后出来的子命令go generate,在编译前生成所需的辅助代码,就可以调用msgp库中的序列化方法了

package main

import (
    "fmt"
)

//go:generate msgp

type Foo struct {
    Bar string  `msg:"bar"`
    Baz float64 `msg:"baz"`
}

func main() {
    fmt.Println("Nothing to see here yet!")
}

上面这段代码关键是部分就是那段注释//go:generate msgp,实际上并不是普通的注释,而是上面说的命令go generate 命令,在这个包下面运行go generate,就会调用msgp命令,这个包下面所有文件只要写有这行注释都会自动生成对应的辅助代码。

$ go generate
======== MessagePack Code Generator =======
>>> Input: "main.go"
>>> Wrote and formatted "main_gen.go"
>>> Wrote and formatted "main_gen_test.go"
$ ls
main.go         main_gen.go     main_gen_test.go  

上面看到我们执行了go generate 命令,就生成了两个新的文件,从文件名我们可以看出主要的辅助代码实际在main_gen.go这个文件中,main_gen_test.go实际是一个测试文件,里面包含了对生成代码的测试,还有序列化的效率输出。
在生成的辅助代码中,实际上就是给Foo这个struct添加了几个方法,包括DecodeMsg,EncodeMsg,MarshalMsg,UnmarshalMsg这些编码、解码、序列化和反序列化方法,还有一个MsgSize,返回被序列化的数据所需的最大字节数。生成的代码太长,这里就不贴出来了,详细代码可以去msgp库的git仓库查看,或者自己动手生成。
上面说到我们调用go generate命令,实际是调用了msgp这个命令,因此实际上我们可以直接调用这个命令。

$ msgp
No file to parse.

直接不带参数,输出了一条错误信息,无文件解析,那么肯定是少了某些参数,根据经验,我们带上-h参数

$ msgp -h
Usage of msgp:
  -file string
        input file
  -io
        create Encode and Decode methods (default true)
  -marshal
        create Marshal and Unmarshal methods (default true)
  -o string
        output file
  -tests
        create tests and benchmarks (default true)
  -unexported
        also process unexported types

果然,msgp命令运行需要的参数出来了,根据它的解释,解析某个文件需要后面接 -file 加文件名,其它的参数都有默认值,我们先删掉之前生成的文件,直接用msgp命令试一下

$ rm main_gen.go main_gen_test.go
kingsoftdeMac-mini:msgptest kingsoft$ msgp -file main.go
======== MessagePack Code Generator =======
>>> Input: "main.go"
>>> Wrote and formatted "main_gen.go"
>>> Wrote and formatted "main_gen_test.go"

跟预期的结果一样,就是之前go generate命令一样的结果,因此可以知道,在代码中输入//go:generate msgp,则表示在执行go generate命令时,实际调用的是msgp -file + 对应文件名。那么如果我们需要添加其它的参数该怎么做呢?对,就是你想的那样,直接在//go:generate msgp后添加,比如只需要序列化,不需要编码,//go:generate msgp -io=false 在生成代码时,DecodeMsg,EncodeMsg就不会生成;-marshal同理;想自定义生成的文件名,-o=myfilename;不需要生成测试文件,-tests=false 等等,就不一一列举了。

到这里,msgp在golang中如何使用就介绍到这里了。什么?你说我根本没介绍使用啊,这只是生成了辅助代码。。。呵呵,确实,不过方法都给你生成了,直接调用不就完了么哈哈,这里篇幅有限,就不举例了。

使用感想

我需要在项目中使用msgp,是因为之前项目中大量使用的JSON确实已经对项目的性能造成了瓶颈,使用msgp一开始是为了解决JSON太大,占用redis缓存太多,导致可缓存数据不多,命中率不高的问题。更换了msgp后,大小问题确实解决了,但实际上并不是很理想,大概就减少了个15%左右的空间,但另我想不到的是,还有个意外收获,它确实是比之前的JSON解析快得多了,直接把整个项目对系统的负载都降了下来,简直惊喜。

这里的坑并不是指msgp的坑,而是我再安装过程中遇到的坑。前几天电脑磁盘坏了,换了个新的,重新搭建了golang环境,也重新安装了msgp,然而在我更新了一个字段需要重新生成代码的时候,运行msgp,却报了一个错

exec: "msgp": executable file not found in $PATH

很好理解,就是在path中找不到msgp这个命令,在百度google都找不到结果后,仔细查看go环境的配置发现其中一个环境配置错了,导致找不到msgp程序,就是go bin环境,go get安装的工具都安装在go bin目录下,需要配置正确才能正确运行。

另外这种需要生成辅助代码也确实有个不好的地方,那就是每次需要添加个参数,都需要重新运行更新一遍代码,不然编译不过,也有点坑啊o(╯□╰)o

以上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 本文简单介绍 Golang 提供的命令。我们执行 go help [command] 可以查看具体命令的帮助信息。...
    juniway阅读 1,977评论 0 2
  • 人们被藏在夜晚 那儿黑暗包裹住他 在时间牺牲的时候 它们释放着遥远的梦 清晨的镜子里陈列着性 那有太阳浸泡在水里 ...
    egg128_3918阅读 339评论 0 1
  • 《琉璃瓦》是张爱玲的经典小说。看了好几遍,每看一遍,都有不同的收获,不同的感触。特别是对人物的描写,简直就是一副水...
    余小头阅读 8,833评论 1 5