[转]序列化悍将Protobuf-Net,入门动手实录

最近在研究web api 2,看了一篇文章,讲解如何提升性能的,

在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打算了解下这个利器

 

1:安装篇

谷歌官方没有提供.net的实现,所以在nuget上找了一个移植的

Nuget里搜索Protobuf-net,下载,自动添加到项目中

 

2:定义数据结构 

复制代码
using ProtoBuf;namespace ConsoleApplication1
{[ProtoContract]class Person{[ProtoMember(1)]public int Id { get; set; }[ProtoMember(2)]public string Name { get; set; }[ProtoMember(3)]public Address Address { get; set; }}[ProtoContract]class Address{[ProtoMember(1)]public string Line1 { get; set; }[ProtoMember(2)]public string Line2 { get; set; }}
}
复制代码

  

3:封装简单操作类

按照作者使用习惯,简单提供了一个Helper类

复制代码
using System.IO;
using System.Text;
using ProtoBuf;namespace ConsoleApplication1
{public class ProtobufHelper{/// <summary>/// 序列化/// </summary>/// <typeparam name="T"></typeparam>/// <param name="t"></param>/// <returns></returns>public static string Serialize<T>(T t){using (MemoryStream ms = new MemoryStream()){Serializer.Serialize<T>(ms, t);return Encoding.UTF8.GetString(ms.ToArray());}}/// <summary>/// 反序列化/// </summary>/// <typeparam name="T"></typeparam>/// <param name="content"></param>/// <returns></returns>public static T DeSerialize<T>(string content){using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(content))){T t = Serializer.Deserialize<T>(ms);return t;}}}
}
复制代码

 

4:操作体验

代码很简单,就不分开贴了

复制代码
using System;
using System.Collections.Generic;
using System.IO;namespace ConsoleApplication1
{class Program{static void Main(string[] args){var p1 = new Person{Id = 1,Name = "八百里开外",Address = new Address{Line1 = "Line1",Line2 = "Line2"}};var p2 = new Person{Id = 2,Name = "一枪",Address = new Address{Line1 = "Flat Line1",Line2 = "Flat Line2"}};List<Person> pSource = new List<Person>() { p1, p2 };string content = ProtobufHelper.Serialize<List<Person>>(pSource);Console.Write(content);//写入文件File.WriteAllText("D://hello.txt", content);Console.WriteLine("\r\n****解析部分*****");List<Person> pResult = ProtobufHelper.DeSerialize<List<Person>>(content);foreach (Person p in pResult){Console.WriteLine(p.Name);}Console.Read();}}
}
复制代码

控制台运行结果

 

同样的数据,和Json所占用空间对比,高下立判

 

后记

protobuf虽然有千般好,但是我们是在 web api上使用的,前台js解析不了Protobuf,所以只能用Json咯~!

StackService虽然Github上有2K多个Star,但是收费的。。同样的事情web api 2也能做到,所以也略过它。

最终作者选择了跑分测试里面的第二名Jil  https://github.com/kevin-montrose/Jil

 

 


 

1. With very minimal annotation on the class level

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)] // only required on the class level
class PersonEntity
{public string FirstName { get; set; }public string LastName { get; set; }
}

 

2. Without any annotation (using RuntimeTypeModel)

static void InitializeProtobufRunTime()
{var assembly = Assembly.GetAssembly(typeof(PlainEntities.PersonEntity));var types = assembly.GetTypes();foreach (var t in types.Where(x => x.Namespace.Contains("PlainEntities"))){Console.WriteLine("Processing {0}", t.FullName);var meta = RuntimeTypeModel.Default.Add(t, false);var index = 1;// find any derived class for the entityforeach (var d in types.Where(x => x.IsSubclassOf(t))){var i = index++;Console.WriteLine("\tSubtype: {0} - #{1}", d.Name, i);meta.AddSubType(i, d);}// then add the propertiesforeach (var p in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Where(x => x.GetSetMethod() != null)){var i = index++;Console.WriteLine("\tProperty: {0} - #{1}", p.Name, i);meta.AddField(i, p.Name);}}
}

 

And both the above works quite well without any performance differences.


------------------
TestBinaryEntities
------------------
Process: 100000 items, MemorySize: 7400705, Completed in: 3877 ms, Serialization took: 676 ms, Deserialization took: 2948 ms

----------------------------------
TestProtobufFullyAnnotatedEntities
----------------------------------
Process: 100000 items, MemorySize: 3983490, Completed in: 682 ms, Serialization took: 164 ms, Deserialization took: 253 ms

-------------------------------------
TestProtobufImplicitAnnotatedEntities
-------------------------------------
Process: 100000 items, MemorySize: 3983490, Completed in: 595 ms, Serialization took: 104 ms, Deserialization took: 210 ms

-------------------------------
TestProtobufRuntimeRegistration
-------------------------------
Processing ProtobufTestConsole.PlainEntities.BaseEntity
Subtype: PersonEntity - #1
Property: Id - #2
Property: Gender - #3
Processing ProtobufTestConsole.PlainEntities.PersonEntity
Property: FirstName - #1
Property: LastName - #2
Property: Age - #3
Process: 100000 items, MemorySize: 4083490, Completed in: 646 ms, Serialization took: 113 ms, Deserialization took: 232 ms

Looking forward to get this in :)

Also attached the sample project for reference

 

转载于:https://www.cnblogs.com/zhahost/p/5813627.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/403180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 内核打印级别

printk的打印级别 #define KERN_EMERG "<0>" /* system is unusable */ #define KERN_ALERT "<1>" /* action must be taken immediately */ #define KERN_CRIT "<2>" /* critical conditions */ #define KERN_ERR "…

C# 文件操作详解(三)---------Directory类

前面两篇介绍了File类和FileInfo类&#xff0c;对于文件的操作基本够用&#xff0c;但是后面还会补充一下FileStream相关的操作&#xff0c;例如StreamReader和StreamWriter的内容。本文主要介绍Directory类的使用&#xff0c;让我们一起看一下Directory类为我们提供了哪些操作…

Libusb开发教程一 安装

1. 从官网下载需要使用的离线资源包&#xff1a; 进入 libusb.info 的 Download 页 下载 libusb-1.0.9.tar.bz2 下载 libusb-compat-0.1.4.tar.bz2 2. 实验平台 OS: Ubuntu16.04 Kernel: 4.4.0 3. 安装过程 <1> 拷贝步骤一中的离线包到 Linux 系统目录&#xff0c;一般…

WIN10解包分区和磁盘分区教程

From: https://thinkpad.bbs.taobao.com/detail.html?postId5390151 新机到手第一件事情就是要系统解包和磁盘分区。建议在安装和卸载软件之前&#xff0c;进行磁盘分区&#xff0c;不然有可能只能分出原空间的50%&#xff0c;想要分更多空间&#xff0c;只能还原系统了。 一、…

element自定义图标;element自定义icon;element-ui自定义tab栏图标;

一、场景&#xff1a;element-ui本身提供了图标&#xff0c;但是不全面或者开发时候需要使用自定义图标展示。此时可以用到elemenUi的自定义图标。参考链接 二、html使用&#xff0c;和正常的element的 图标 i 标签使用一样&#xff0c;使用设置的类名class即可&#xff1a; &…

canvas文字居中;canvas画布文字右对齐;canvas画布文字左对齐;canvas文字自动换行;canvas设置行间距;

canvas参考手册 场景&#xff1a;画布绘制文本&#xff0c;使用 context.fillText(text,x,y,maxWidth)。文本对其也就是设置xy坐标问题。 以下的画布设定宽度假设都是width&#xff1a;500 一、canvas文本左对齐&#xff1a; 就是x轴设置为0即可。 var cdocument.getElementBy…

与朱元思书

风烟俱净&#xff0c;天山共色。从流飘荡&#xff0c;任意东西。自富阳至桐庐一百许里&#xff0c;奇山异水&#xff0c;天下独绝。 水皆缥碧&#xff0c;千丈见底。游鱼细石&#xff0c;直视无碍。急湍甚箭&#xff0c;猛浪若奔。 夹岸高山&#xff0c;皆生寒树&#xff0c;负…

el-cascader回显失败;el-cascader回显不出来

—我的是省市联动&#xff0c;选择时候是正常的&#xff0c;得到的绑定值是数组 [‘安徽’,‘黄山’]&#xff0c;没问题&#xff1b; 但是在详情查看时候&#xff0c;回显成[‘安徽’,‘黄山’]&#xff0c;下拉框却不显示回显值。 —原因&#xff1a;虽然data里初始化声明变量…

No grammar constraints (DTD or XML schema).....两种解决方法

From: http://www.cnblogs.com/yqskj/archive/2013/01/11/2857065.html 方法一&#xff1a;常用方法 关闭XML验证 工具栏&#xff1a;windows > preferences > xml > xml files > validation > Indicate when no grammar is specified:选择Ignore即可。 方法二…

数字金额加逗号;js给数字加三位一逗号间隔的两种方法;js数据格式化

需求&#xff1a;数字金额&#xff0c;按照三位一个逗号显示。既 千 百万 十亿 或者是按照固定的几位一个逗号展示。 方法1&#xff1a; <script type "text/javascript">//保留三位小数&#xff0c;toLocaleString() 方法可把一个 Number 对象转换为本地格…

项目管理软件伙伴https://www.huobanyun.cn/

现在项目管理软件市面上很多&#xff0c;但能够完全适合每家公司需求的比较难找&#xff0c;因为众口难调&#xff0c;每家公司都有自己的特殊情况&#xff0c;所以&#xff0c;建议考虑下有比较齐全的基础功能的标准化软件产品&#xff0c;同时又在项目管理开发能力上比较突出…

eclipse配置

eclipse 算是跨平台的开发工具了&#xff0c;而且使用的人群很多&#xff0c;虽然网上有很多答案&#xff0c;但我还是想整理下自己的答案&#xff0c;方便日后查询&#xff1a; 1. 编码设置 2. 解决No grammar constraints (DTD or XML schema) 3. [WARNING] Using platform …

el-form表单新增表单项动态校验;el-form校验动态表单v-if不生效;

场景&#xff1a;本文是两种表单校验 1.对于数组for循环&#xff0c;校验每一项 2.对于两个不同的字段&#xff0c;分别v-if显示隐藏的校验 一、新增和删除表单项&#xff0c;动态校验。 el-form表单动态动态新增表单进行校验。直接参考 动态增减表单项 以下代码可直接复制&…

MT7628如何控制GPIO

查看datasheet和确认GPIO复用引脚scheme 通过查看mt7628 datasheet可以明确复用关系&#xff1a; 在这里我以I2S对应的GPIO引脚为例。 查看 mt7628an.dtsi 文件中对gpio的注册 $(TOPDIR)假定为宿主机上 OpenWrt 的编译目录。 在$(TOPDIR)/target/linux/ramips/dts/mt7628an.d…

.Net Core集成Office Web Apps(一)

最近开始学习.Net Core&#xff0c;并使用Visual Studio Code工具来开发。感觉开发起来特别的方便&#xff0c;但是有个头疼的地方&#xff1a;许多的类库被修改了&#xff0c;一时半会儿还熟悉不了&#xff0c;需要查阅官方API。。。 Microsoft Office Web Apps&#xff08;以…

el-upload上传组件的动态添加;el-upload动态上传文件;el-upload区分文件是哪个组件上传的。

需求&#xff1a;正常我们上传都是一个固定的文件传到固定的后端字段里去。 但是有可能遇到&#xff0c;这种自定义新增多个上传组件&#xff0c;也就是遍历数组似的多个同样的上传组件 此时就遇到一个问题&#xff1a;因为是遍历出来的上传组件&#xff0c;导致上传成功:on-su…

openwrt gpio控制与使用

查看datasheet和确认GPIO复用引脚scheme 通过查看mt7628 datasheet可以明确复用关系&#xff1a; 在这里我以I2S对应的GPIO引脚为例。 查看 mt7628an.dtsi 文件中对gpio的注册 $(TOPDIR)假定为宿主机上 OpenWrt 的编译目录。 在$(TOPDIR)/target/linux/ramips/dts/mt7628an.d…

git 配置图形比较工具

2019独角兽企业重金招聘Python工程师标准>>> 以meld为例&#xff0c;安装方式是sudo apt-get install A. 在/usr/local/bin 目录下创建extDiff 文件(注意: 目录可以是任意) cd /usr/local/bin sudo gedit /usr/local/bin 内容为: #!/bin/bash /usr/bin/meld "$…

推荐!!!前端将url转成blob和blob转成url;前端将文件流读取成url;前端将blob文件读取出url预览和下载

一般后端返回的地址&#xff0c;前端通过返回blob读取出url&#xff0c;然后使用a标签下载 方式一&#xff1a;通过接口将后端返回的文件流blob读取出url&#xff08;推荐推荐&#xff09; downLoadFileImg (fileUrl, fileName) {// 可下载&#xff0c;名称也有效 -- 推荐cons…