Protocol buffers--python 实践(二) protocol buffers vs json
为什么专门开一个坑,来使用pb。放弃本在各平台上都支持得很好的json而使用pb的一个归根到底的理由,就是希望在保证强类型和跨平台的情况下,能够更轻,更快,更简单。既然是奔着这个目标去的,到底多快我需要一个合理的解释。
在使用pure python官方库的的情况下,对比了pb和json标准库,还有simplejson库的速度。
使用的.proto文件文件如下:
syntax = "proto2";
package hello_word;
message SayHi {
required int32 id = 1;
required string something = 2;
optional string extra_info = 3;
}
python文件可以根据这个生成对应的SayHi obejct。
测试各库序列化速度的代码如下所示:
# coding: utf-8
import timeit # 序列化
x = """
say_hi.SerializeToString()
""" y = """
json.dumps(ppa)
""" z = """
simplejson.dumps(pl)
""" print min(timeit.repeat(stmt=x, setup="import say_hi_pb2;"
"say_hi = say_hi_pb2.SayHi();"
"say_hi.id = 13423;"
"say_hi.something = 'axiba';"
"say_hi.extra_info = 'xiba';", repeat=5, number=100000)) print min(timeit.repeat(stmt=y, setup="import json; "
"ppa={"
"'id': 13423,"
"'something': 'axiba',"
"'extra_info': 'xiba',"
"};", repeat=5, number=100000)) print min(timeit.repeat(stmt=z, setup="import simplejson; "
"pl={"
"'id': 13423,"
"'something': 'axiba',"
"'extra_info': 'xiba',"
"};", repeat=5, number=100000)) 输出:
1.08438277245
0.398800134659
0.707333087921
测试各库反序列化速度的代码如下所示:
# coding: utf-8
import timeit # 反序列化
x = """
say_hi.ParseFromString(p)
"""
y = """
json.loads(p1)
"""
z = """
simplejson.loads(p2)
""" print min(timeit.repeat(stmt=x, setup="import say_hi_pb2;"
"say_hi = say_hi_pb2.SayHi();"
"say_hi.id = 13423;"
"say_hi.something = 'axiba';"
"say_hi.extra_info = 'xiba';"
"p = say_hi.SerializeToString()", repeat=5, number=100000)) print min(timeit.repeat(stmt=y, setup="import json; "
"ppa={"
"'id': 13423,"
"'something': 'axiba',"
"'extra_info': 'xiba',"
"};"
"p1 = json.dumps(ppa)", repeat=5, number=100000)) print min(timeit.repeat(stmt=z, setup="import simplejson; "
"pl={"
"'id': 13423,"
"'something': 'axiba',"
"'extra_info': 'xiba',"
"};"
"p2 = simplejson.dumps(pl)", repeat=5, number=100000))
输出:
0.924090862274
0.492631912231
0.283575057983
从上面的数据可以看出,在我使用的版本3.1.0.post1的情况下,纯python实现pb序列化的速度略慢于json原生库两倍多,比simplejson库慢百分之30。在反序列化的速度测试中,依然是pb速度最慢两倍慢于原生json库,慢于simplejson库3倍多。这样看起来差距似乎被优化得不那么大了。记得以前在使用pb2.x库的时候,python序列化常慢于simplejson 3倍以上是非常正常的事情。各分析性能的文章都可以看到 too slow这个描述。由于二进制存储,以及pb独特的编码二进制的方式,从大小的角度来说,pb远远小于json,但是速度连json都快不过,我们有什么理由放弃使用方便可依赖的json转而使用pb呢?这的确没有什么说服力。
然而,pb官方提供了一个c++实现 runtime for python,按照实践一中的方法,安装好最新的pb库,并且按照文档编译好,然后安装python 的c++实现,就可以让pb使用c++实现进行序列化反序列。其他生成代码之类的所有不用变,调用代码也不用变,只需要安装好就可以了。安装好之后可以看到
Using /Users/piperck/Desktop/grpc/lib/python2.7/site-packages
Finished processing dependencies for protobuf==3.1.0
再次使用pip list查看我们的pb的时候可以发现,已经被该库替代。
让我们来重新运行一下 序列化和反序列化的代码:
序列化输出:
0.085785150528
0.403172016144
0.755691051483 反序列化输出:
0.090231180191
0.499733924866
0.297739028931
可以看到几乎比pure python的实现快近10倍。如果把序列化和反序列按照一次计算进行计算的话,也比我们通常使用的simplejson库快上4到5倍。再频繁调用序列化反序列化的应用中,可以说还是比较大的性能提升了,可以使得你的代码更轻更快,而且强类型映射可以检查错误。
别以为到这里就完了。还有一个更快速的库,但是现在只支持proto2,叫Pyrobuf Library。基于cPython实现,根据作者的说法,他要比c++ backend for python 还要快上2-4倍。让我们来尝试一下。
首先安装一下:
pip install pyrobuf
如果不行可以尝试使用:
pip install pyrobuf -v -v -v --upgrade --force --no-cache
安装好之后,按照官网的提示,使用pyrobuf 的 cli命令行界面,对.proto文件进行编译,得到.pxd和.pyx文件,还有.o和.c还有.so的文件(注意他们需要在同一个文件夹下)。
一切完成之后书写代码 测试速度:
import timeit o = """
p.SerializeToString()
""" print min(timeit.repeat(stmt=o, setup=
"from hello_world_say_hi_proto import SayHi;"
"p = SayHi();"
"p.id = 3;"
"p.something = 'axiba';"
"p.extra_info = 'xiba'", repeat=5, number=100000)) o = """
p.ParseFromString(oi)
""" print min(timeit.repeat(stmt=o, setup=
"from hello_world_say_hi_proto import SayHi;"
"p = SayHi();"
"p.id = 3;"
"p.something = 'axiba';"
"p.extra_info = 'xiba';"
"oi = p.SerializeToString()", repeat=5, number=100000)) 输出:
0.069412946701
0.0525119304657
对比上面使用c++ backend的pb来看,反序列化勉强快到2倍,而序列化几乎没有什么特别大的优势。可能得益于使用最新版pb3.10的关系,在google的不断优化下,已经没有那么大差距了吧。因为使用cPython比较麻烦,还会多出不少编译文件。所以没什么提升的情况下,按照个人的需求使用吧。
Reference:
https://github.com/google/protobuf/tree/master/python pb-github库
https://github.com/appnexus/pyrobuf Pyrobuf Library
http://techblog.appnexus.com/blog/2015/12/22/pyrobuf-a-faster-python-protobuf-library-written-in-cython/ pyrobuf-a-faster-python-protobuf-library-written-in-cython
Protocol buffers--python 实践(二) protocol buffers vs json的更多相关文章
- 机器学习算法与Python实践之(二)支持向量机(SVM)初级
机器学习算法与Python实践之(二)支持向量机(SVM)初级 机器学习算法与Python实践之(二)支持向量机(SVM)初级 zouxy09@qq.com http://blog.csdn.net/ ...
- P4语言编程快速开始 实践二
参考:P4语言编程快速开始 上一篇系列博客:P4语言编程快速开始 实践二 Demo 2 本Demo所做的修改及实现的功能: 为simple_router添加一个计数器(counter),该计数器附加( ...
- WebSocket原理与实践(二)---WebSocket协议
WebSocket原理与实践(二)---WebSocket协议 WebSocket协议是为了解决web即时应用中服务器与客户端浏览器全双工通信问题而设计的.协议定义ws和wss协议,分别为普通请求和基 ...
- Python实践:开篇
一.概述 Python实践 是应用Python解决实际问题的案例集合,这些案例中的Python应用通常 功能各异.大小不一. 该系列文章是本人应用Python的实践总结,会不定期更新. 二.目录 Py ...
- Python实践之(七)逻辑回归(Logistic Regression)
机器学习算法与Python实践之(七)逻辑回归(Logistic Regression) zouxy09@qq.com http://blog.csdn.net/zouxy09 机器学习算法与Pyth ...
- 机器学习算法与Python实践之(四)支持向量机(SVM)实现
机器学习算法与Python实践之(四)支持向量机(SVM)实现 机器学习算法与Python实践之(四)支持向量机(SVM)实现 zouxy09@qq.com http://blog.csdn.net/ ...
- 机器学习算法与Python实践之(三)支持向量机(SVM)进阶
机器学习算法与Python实践之(三)支持向量机(SVM)进阶 机器学习算法与Python实践之(三)支持向量机(SVM)进阶 zouxy09@qq.com http://blog.csdn.net/ ...
- 机器学习算法与Python实践之(五)k均值聚类(k-means)
机器学习算法与Python实践这个系列主要是参考<机器学习实战>这本书.因为自己想学习Python,然后也想对一些机器学习算法加深下了解,所以就想通过Python来实现几个比较常用的机器学 ...
- (转) K-Means聚类的Python实践
本文转自: http://python.jobbole.com/87343/ K-Means聚类的Python实践 2017/02/11 · 实践项目 · K-means, 机器学习 分享到:1 原文 ...
- 机器学习算法与Python实践之(六)二分k均值聚类
http://blog.csdn.net/zouxy09/article/details/17590137 机器学习算法与Python实践之(六)二分k均值聚类 zouxy09@qq.com http ...
随机推荐
- UVA11584-Partitioning by Palindromes(动态规划基础)
Problem UVA11584-Partitioning by Palindromes Accept: 1326 Submit: 7151Time Limit: 3000 mSec Problem ...
- UVA211-The Domino Effect(dfs)
Problem UVA211-The Domino Effect Accept:536 Submit:2504 Time Limit: 3000 mSec Problem Description ...
- sql 查询所有子节点示例
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code <!-- 查询机构的所有子机构 --> <select id=&qu ...
- 8.oop-多态
一.继承1.定义:子类继承父类,会继承父类的属性和方法2.语法:extends关键字 子类 extends 父类3.特点:java中的继承是单一继承,子类只能继承一个父类,但是父类可以有多个子类4.用 ...
- ROS 创建服务和请求
教程 维基 http://wiki.ros.org/cn/ROS/Tutorials 快速过程 创建包 $ cd ~/catkin_ws $ mkdir ~/catkin_ws/src $ cd ~/ ...
- DES对称加密算法详解和c++代码实现(带样例和详细的中间数据)
特点: 1.DES是对称性加密算法,即加密和解密是对称的,用的是同一个密钥 2.DES只处理二进制数据,所以需要将明文转换成为2进制数据 3.DES每次处理64位的数据,所以应该将明文切割成64位的分 ...
- odoo常用widget
widget=”statusbar” 头部状态条标签widget=”email” 电子邮件地址标签widget=”selection” 下拉选择标签widget=”mail_followers” ...
- linux学习问题总结
目录 一.环境变量和普通变量的区别 二.rsyslog和logrotate会不会丢记录的问题 三.为什么有些文件夹大小不是4096的整数倍 四.reboot和shutdown等软链接实现原理 五.sy ...
- React-菜鸟学习笔记(二)
这篇新颖的东西是React的组件的封装和引用 <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...
- .NetCore实践爬虫系统(一)解析网页内容
爬虫系统的意义 爬虫的意义在于采集大批量数据,然后基于此进行加工/分析,做更有意义的事情.谷歌,百度,今日头条,天眼查都离不开爬虫. 今日目标 今天我们来实践一个最简单的爬虫系统.根据Url来识别网页 ...