C#中使用ProtoBuf提高序列化速度对比二进制序列化

场景

ProtoBuf

protocolbuffer是google 的一种数据交换的格式,它独立于语言,独立于平台。
google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。
由于它是一种二进制的格式,比使用xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。
作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。

.proto

类似于.json和.xml,ProtoBuf有自己的文件格式.proto文件格式。

也有自己的语法,具体可以搜索.proto语法。

示例源码下载

https://download.csdn.net/download/badao_liumang_qizhi/11583786

实现

新建.proto文件

这里使用的是EditPlus新建txt文件,按照其语法要求编写如下request.proto文件。

package ProtoBufTest;

message Request {
    required int32 id = 1;
    required string password = 2;
}

注:

package ProtoBufTest 要与项目的namespace相对应。

message 后面就是要生成的类名。

required表示必须的,int32对应int类型,string对应string类型。

=1是固定的语法格式,记得往后递增。

最终文件如下

 

.ptoto文件生成类(.cs文件)

生成工具ProtoGen下载:

https://download.csdn.net/download/badao_liumang_qizhi/11583806

将上面新建的文件放在与protogen.exe同目录下

 

然后在此处打开命令行(Windows下是按住shift,在当前目录右击选择在此处打开命令行)。

输入命令:

protogen.exe   -i:request.proto    -o:Request.cs

 

注:

-i后面跟的是上面新建的proto文件

-o后面跟的是要生成的.cs文件

运行后会在同目录下生成Request.cs

 

生成的文件内容

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// Generated from: request.proto
namespace ProtoBufTest
{
  [global::System.Serializable, global::ProtoBuf.ProtoContract(Name=@"Request")]
  public partial class Request : global::ProtoBuf.IExtensible
  {
    public Request() {}
   
    private int _id;
    [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name=@"id", DataFormat = global::ProtoBuf.DataFormat.TwosComplement)]
    public int id
    {
      get { return _id; }
      set { _id = value; }
    }
    private string _password;
    [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name=@"password", DataFormat = global::ProtoBuf.DataFormat.Default)]
    public string password
    {
      get { return _password; }
      set { _password = value; }
    }
    private global::ProtoBuf.IExtension extensionObject;
    global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
      { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }
  }
 
}

项目中引进

新建窗体项目,然后将上面生成的Request.cs文件复制到项目下。

此时打开cs文件会报错,此时需要引进dll(动态链接库文件)--protobuf-net.dll。

protobuf-net.dll下载:

https://download.csdn.net/download/badao_liumang_qizhi/11583772

添加引用

打开资源管理器--右击引用--添加

 

选择浏览--右下角浏览--确定

 

实现ProtoBuf序列化

打开窗体设计器,拖拽一个按钮Button,然后双击按钮进入其点击事件。

 private void button1_Click(object sender, EventArgs e)
        {
            //序列化操作
            Request request = new Request();
            request.id = 1;
            request.password = "123";
            //计时器计时
            Stopwatch sw = new Stopwatch();
            //启动计时器
            sw.Start();
            //执行序列化
            MemoryStream ms = new MemoryStream();
            Serializer.Serialize<Request>(ms, request);
            byte[] data = ms.ToArray();
            //停止计时器
            sw.Stop();
            //输出计时时间
            Console.WriteLine("使用ProtoBuf序列化:" + sw.Elapsed);    
        }

注:

在上面调用Serializer时引入的是ProtoBuf自带的。

 

对比二进制序列化

右击项目-添加-类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ProtoBufTest
{
    [Serializable]
    class Person
    {

        public Person(int id ,string password) {
            this.Id = id;
            this.Password = password;
        }
        private int id;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        private string password;

        public string Password
        {
            get { return password; }
            set { password = value; }
        }
    }
}

注:记得要添加可序列化的标识[Serializable]

在上面的窗体中在拖拽一个Button,双击进入其点击事件。

private void button2_Click(object sender, EventArgs e)
        {
            Person per = new Person(18,"张三");
            //计时器计时
            Stopwatch sw = new Stopwatch();
            sw.Start();
            FileStream fs = new FileStream(filePath, FileMode.Create);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(fs, per);
            fs.Close();
            sw.Stop();
            Console.WriteLine("二进制序列化:" + sw.Elapsed);
        }

对比效果

运行项目,先点击二进制序列化按钮,再点击ProtoBuf序列化按钮。

 

 


 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霸道流氓气质

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值