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

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

1:安装篇

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

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

2:定义数据结构

  1. using ProtoBuf;
  2.  
  3. namespace ConsoleApplication1
  4. {
  5. [ProtoContract]
  6. class Person
  7. {
  8. [ProtoMember(1)]
  9. public int Id { get; set; }
  10. [ProtoMember(2)]
  11. public string Name { get; set; }
  12. [ProtoMember(3)]
  13. public Address Address { get; set; }
  14. }
  15. [ProtoContract]
  16. class Address
  17. {
  18. [ProtoMember(1)]
  19. public string Line1 { get; set; }
  20. [ProtoMember(2)]
  21. public string Line2 { get; set; }
  22. }
  23. }

3:封装简单操作类

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

  1. using System.IO;
  2. using System.Text;
  3. using ProtoBuf;
  4.  
  5. namespace ConsoleApplication1
  6. {
  7. public class ProtobufHelper
  8. {
  9. /// <summary>
  10. /// 序列化
  11. /// </summary>
  12. /// <typeparam name="T"></typeparam>
  13. /// <param name="t"></param>
  14. /// <returns></returns>
  15. public static string Serialize<T>(T t)
  16. {
  17. using (MemoryStream ms = new MemoryStream())
  18. {
  19. Serializer.Serialize<T>(ms, t);
  20. return Encoding.UTF8.GetString(ms.ToArray());
  21. }
  22. }
  23.  
  24. /// <summary>
  25. /// 反序列化
  26. /// </summary>
  27. /// <typeparam name="T"></typeparam>
  28. /// <param name="content"></param>
  29. /// <returns></returns>
  30. public static T DeSerialize<T>(string content)
  31. {
  32. using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(content)))
  33. {
  34. T t = Serializer.Deserialize<T>(ms);
  35. return t;
  36. }
  37. }
  38. }
  39. }

4:操作体验

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4.  
  5. namespace ConsoleApplication1
  6. {
  7. class Program
  8. {
  9. static void Main(string[] args)
  10. {
  11.  
  12. var p1 = new Person
  13. {
  14. Id = 1,
  15. Name = "八百里开外",
  16. Address = new Address
  17. {
  18. Line1 = "Line1",
  19. Line2 = "Line2"
  20. }
  21. };
  22.  
  23. var p2 = new Person
  24. {
  25. Id = 2,
  26. Name = "一枪",
  27. Address = new Address
  28. {
  29. Line1 = "Flat Line1",
  30. Line2 = "Flat Line2"
  31. }
  32. };
  33.  
  34. List<Person> pSource = new List<Person>() { p1, p2 };
  35.  
  36. string content = ProtobufHelper.Serialize<List<Person>>(pSource);
  37.  
  38. Console.Write(content);
  39. //写入文件
  40. File.WriteAllText("D://hello.txt", content);
  41.  
  42. Console.WriteLine("\r\n****解析部分*****");
  43.  
  44. List<Person> pResult = ProtobufHelper.DeSerialize<List<Person>>(content);
  45.  
  46. foreach (Person p in pResult)
  47. {
  48. Console.WriteLine(p.Name);
  49. }
  50.  
  51. Console.Read();
  52. }
  53. }
  54. }

控制台运行结果

同样的数据,和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

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

2. Without any annotation (using RuntimeTypeModel)

  1. static void InitializeProtobufRunTime()
  2. {
  3. var assembly = Assembly.GetAssembly(typeof(PlainEntities.PersonEntity));
  4. var types = assembly.GetTypes();
  5. foreach (var t in types.Where(x => x.Namespace.Contains("PlainEntities")))
  6. {
  7. Console.WriteLine("Processing {0}", t.FullName);
  8. var meta = RuntimeTypeModel.Default.Add(t, false);
  9. var index = ;
  10.  
  11. // find any derived class for the entity
  12. foreach (var d in types.Where(x => x.IsSubclassOf(t)))
  13. {
  14. var i = index++;
  15. Console.WriteLine("\tSubtype: {0} - #{1}", d.Name, i);
  16. meta.AddSubType(i, d);
  17. }
  18.  
  19. // then add the properties
  20. foreach (var p in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).Where(x => x.GetSetMethod() != null))
  21. {
  22. var i = index++;
  23. Console.WriteLine("\tProperty: {0} - #{1}", p.Name, i);
  24. meta.AddField(i, p.Name);
  25. }
  26. }
  27. }

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

[转]序列化悍将Protobuf-Net,入门动手实录的更多相关文章

  1. 序列化悍将Protobuf-Net,入门动手实录

    最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打算了解下这个利器 1:安装篇 谷歌官方没有提供.n ...

  2. 速度最快的Json序列框架Jil,入门动手实录

    好吧,我又先要贴出跑分图了,出处 Jil是一个面向Json的序列化框架,在Nuget上可以下载到 支持数据类型 值得一提的是,Guid指定带破折号格式(44B2673B-B5CA-477B-A8EA- ...

  3. 序列化悍将Protobuf-Net

    序列化悍将Protobuf-Net,入门动手实录 最近在研究web api 2,看了一篇文章,讲解如何提升性能的, 在序列化速度的跑分中,Protobuf一骑绝尘,序列化速度快,性能强,体积小,所以打 ...

  4. 最快的序列化组件protobuf的.net版本protobuf.net

    Protobuf是google开源的一个项目,用户数据序列化反序列化,google声称google的数据通信都是用该序列化方法.它比xml格式要少的多,甚至比二进制数据格式也小的多.     Prot ...

  5. 数据序列化之protobuf

    数据序列化之protobuf 很多时候需要将一些数据打包,就是把这些数据搞在一起,方便处理.最常见的情况就是把需要传输的数据,当然数据不止一条,打包成一个消息,然后发送出去,接收端再以一定的规则接收并 ...

  6. 序列化之protobuf与avro对比(Java)

    最近在做socket通信中用到了关于序列化工具选型的问题,在调研过程中开始趋向于用protobuf,可以省去了编解码的过程.能够实现快速开发,且只需要维护一份协议文件即可. 但是调研过程中发现了pro ...

  7. 重点关注之自定义序列化方式(Protobuf和Msgpack)

    除了默认的JSON和XML序列化器外,如果想使用其它格式的(比如二进制)序列化器,也是可以的.比如著名的Protobuf和Msgpack,它们都是二进制的序列化器,特点是速度快,体积小.使用方法如下. ...

  8. Protobuf学习 - 入门

    古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 -- 苏轼·<晁错论> 从公司的项目源码中看到了这个东西,觉得挺好用的,写篇博客做下小总结.下面的操作以C++为编程语言,protoc的版 ...

  9. Protobuf 从入门到实战

    简介 从第一次接触Protobuf到实际使用已经有半年多,刚开始可能被它的名字所唬住,其实就它是一种轻便高效的数据格式,平台无关.语言无关.可扩展,可用于通讯协议和数据存储等领域. 优点 平台无关,语 ...

随机推荐

  1. mysql表单输入数据出现中文乱码解决方法

    MySQL会出现中文乱码的原因在于1.server本身设定问题,一般来说是latin1 2.建库建表时没有制定编码格式. 解决方法: 1.建库的时候 CREATE DATABASE test CHAR ...

  2. coreseek 安装及使用方法详解

    coreseek 安装及使用 一般站点都需要搜索功能,如果是php+mysql站点,建议选择coreseek,如果是java站点建议使用lucene,coreseek 是一款很好的中文全文检索/搜索软 ...

  3. Spring_的jar详细说明

    org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spring 2.5.6的时候需要a ...

  4. ubuntu下安装mysql, eclipse, tomcat

    mysql sudo apt-get install mysql-server 进入mysql: mysql -uroot -p 导入数据库: create database [name]; use ...

  5. Network

    App Icon: http://www.easyicon.net/

  6. cocos2d-x学习记录第一篇-环境变量配置

    最近准备学习cocos2d-x,之前一直是做iOS开发的,算是零基础开始学习吧. (此条后来修改,不用配置下面这些东西,下载一个cocosstudio就可以了,直接在里边就创建工程了) 本人用Mac电 ...

  7. Qt - 错误总结 - QObject::connect: Cannot queue arguments of type 'PVCI_CAN_OBJ' (Make sure 'PVCI_CAN_OBJ' is registered using qRegisterMetaType().)

    背景:一个线程通过signal-slot发送PVCI_CAN_OBJ类型的值到主线程中, 错误提示: QObject::connect: Cannot queue arguments of type ...

  8. Lodash.js的库

    1.orderBy _order(数组,排序对象,["asc"]升序或者["desc"]降序)

  9. centos 编程环境

    1,老毛桃/大白菜, iso制作将镜像文件写入u盘2, 安装,修改安装源路径 (手动修改为你的u盘dev)一般为sdb43,   安装时选择桌面安装 4, 更改安装源cd /etc/yum.repos ...

  10. rocketmq生产者部署的机器注意事项

    报错: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'warningP ...