标签: protobuf-net

protobuf-net不比二进制序列化快?

我编写了一个程序来使用XMLSerializer,BinaryFormatter和ProtoBuf序列化一个'Person'类.我认为protobuf-net应该比其他两个更快.Protobuf序列化比XMLSerialization更快,但比二进制序列化慢得多.我的理解不正确吗?请让我明白这一点.感谢您的帮助.

编辑: - 我更改了代码(下面更新)来测量仅序列化的时间,而不是创建流,仍然看到差异.能告诉我为什么吗?

以下是输出: -

人在347毫秒内使用协议缓冲区创建

人在1462毫秒内使用XML创建

人在2毫秒内使用二进制创建

代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization.Formatters.Binary;
namespace ProtocolBuffers
{
    class Program
    {
        static void Main(string[] args)
        {

            string folderPath  = @"E:\Ashish\Research\VS Solutions\ProtocolBuffers\ProtocolBuffer1\bin\Debug";
            string XMLSerializedFileName = Path.Combine(folderPath,"PersonXMLSerialized.xml");
            string ProtocolBufferFileName = Path.Combine(folderPath,"PersonProtocalBuffer.bin");
            string BinarySerializedFileName = Path.Combine(folderPath,"PersonBinary.bin");

            if (File.Exists(XMLSerializedFileName))
            {
                File.Delete(XMLSerializedFileName);
                Console.WriteLine(XMLSerializedFileName + " deleted");
            }
            if (File.Exists(ProtocolBufferFileName))
            {
                File.Delete(ProtocolBufferFileName);
                Console.WriteLine(ProtocolBufferFileName + " deleted");
            }
            if (File.Exists(BinarySerializedFileName))
            {
                File.Delete(BinarySerializedFileName);
                Console.WriteLine(BinarySerializedFileName + " …
Run Code Online (Sandbox Code Playgroud)

serialization protobuf-net

8
推荐指数
2
解决办法
1万
查看次数

如何在Protobuf中发送多种类型的对象?

我正在实现客户端 - 服务器应用程序,并正在研究序列化和传输数据的各种方法.我开始使用Xml Serializers,它工作得很好,但是生成数据很慢,并且生成大对象,特别是当它们需要通过网络发送时.所以我开始研究Protobuf和protobuf-net.

我的问题在于protobuf没有发送类型信息.使用Xml Serializers,我能够构建一个包装器,它将在同一个流上发送和接收任何各种(可序列化的)对象,因为序列化为Xml的对象包含对象的类型名称.

ObjectSocket socket = new ObjectSocket();
socket.AddTypeHandler(typeof(string));  // Tells the socket the types
socket.AddTypeHandler(typeof(int));     // of objects we will want
socket.AddTypeHandler(typeof(bool));    // to send and receive.
socket.AddTypeHandler(typeof(Person));  // When it gets data, it looks for
socket.AddTypeHandler(typeof(Address)); // these types in the Xml, then uses
                                        // the appropriate serializer.

socket.Connect(_host, _port);
socket.Send(new Person() { ... });
socket.Send(new Address() { ... });
...
Object o = socket.Read();
Type oType = o.GetType();

if (oType == typeof(Person))
    HandlePerson(o as …
Run Code Online (Sandbox Code Playgroud)

c# serialization protocol-buffers protobuf-net

8
推荐指数
1
解决办法
5462
查看次数

使用ProtoBuf-Net,如何(反)序列化多维数组?

由于ProtoBuf-Net不支持序列化/反序列化多维数组,我将如何管理我的数组呢?

.net arrays protobuf-net multidimensional-array

8
推荐指数
1
解决办法
2937
查看次数

将自定义ValueProviderFactories添加到ASP.NET MVC3?

我想尝试将一个Protobuf ValueProviderFactory添加到MVC3,以便我可以选择MIME类型并将原始数据反序列化为对象以获取操作参数.我也可以使用它来更改默认的Json序列化程序.

JsonValueProviderFactory.cs这个应该不会太难,但工厂似乎都是硬编码的.

对于Protobuf我可以用IValueProvider做一些事情,但我还没有检查MVC3在收到MIME类型时做了什么application/x-protobuf.

我是以正确的方式来做这件事的吗?

UPDATE

我发现这个博客文章谈论创建一个IValueProvider.然后它在底部提到这改变了MCV2.他将其改为a ValueProviderFactory并致电:

ValueProviderFactories.Factories.Add(new HttpCookieValueProviderFactory());
Run Code Online (Sandbox Code Playgroud)

但在MVC3中,此属性是只读的.

.net asp.net-mvc protobuf-net asp.net-mvc-3

8
推荐指数
1
解决办法
2082
查看次数

Protobuf.net异常 - 检查元数据时超时

尝试使用protobuf.net反序列化对象时,有时会收到以下异常.我很惊讶,因为我从来没有多个线程同时反序列化同一个对象,并且protobuf.net源似乎没有使用任何静态对象进行反序列化.例外确实提出了一个解决方案,但我不确定如何实现,所以欢迎一个例子.

Base Exception Type:
System.TimeoutException: Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection
at ProtoBuf.Meta.RuntimeTypeModel.TakeLock(Boolean& lockTaken)
at ProtoBuf.Meta.RuntimeTypeModel.FindOrAddAuto(Type type, Boolean demand, Boolean addWithContractOnly, Boolean addEvenIfAutoDisabled)
at ProtoBuf.Meta.RuntimeTypeModel.GetKey(Type type, Boolean demand, Boolean getBaseKey)

Inner Exception Type:
System.TimeoutException: Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers …
Run Code Online (Sandbox Code Playgroud)

c# deadlock protobuf-net

8
推荐指数
2
解决办法
2589
查看次数

BinaryFormatter中的引用完整性

Protobuf-net中存在AsReference选项,而BinaryFormatter是一个"图形序列化器",这使我认为BinaryFormatter不维护引用,并且它会复制每个对象.

但我做了一些测试,发现即使对于递归引用,单个BinaryFormatter Serialize()或Deserialize()调用中的所有引用都会被维护.

我可以确认BinaryFormatter确实维护引用吗?这与Protobuf-net有何不同?好像我理解"图形序列化"不正确?我还应该注意什么?

提前致谢.

c# reference protobuf-net binaryformatter

8
推荐指数
1
解决办法
1225
查看次数

使用Protobuf-net序列化分块字节数组的内存使用情况

在我们的应用程序中,我们有一些数据结构,其中包含一个分块的字节列表(当前公开为a List<byte[]>).我们将字节大块化,因为如果我们允许将字节数组放在大对象堆上,那么随着时间的推移,我们会遇到内存碎片.

我们也开始使用Protobuf-net来序列化这些结构,使用我们自己生成的序列化DLL.

但是我们注意到Protobuf-net在序列化时会创建非常大的内存缓冲区.浏览源代码看起来似乎它可能无法刷新其内部缓冲区,直到整个List<byte[]>结构被写入,因为它需要在缓冲区前面写入总长度.

不幸的是,这首先解决了我们的工作,首先将字节分块,最终由于内存碎片而给我们OutOfMemoryExceptions(异常发生在Protobuf-net尝试将缓冲区扩展到84k以上时,这显然是在LOH,我们的整体进程内存使用率相当低.

如果我对Protobuf-net如何工作的分析是正确的,那么有没有解决这个问题的方法呢?


更新

根据Marc的回答,这是我尝试过的:

[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase
{
}

[ProtoContract]
public class A : ABase
{
    [ProtoMember(1, DataFormat = DataFormat.Group)]
    public B B
    {
        get;
        set;
    }
}

[ProtoContract]
public class B
{
    [ProtoMember(1, DataFormat = DataFormat.Group)]
    public List<byte[]> Data
    {
        get;
        set;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后序列化它:

var a = new A();
var b = new B();
a.B = b;
b.Data = new List<byte[]>
{
    Enumerable.Range(0, 1999).Select(v => …
Run Code Online (Sandbox Code Playgroud)

c# chunking protobuf-net large-object-heap

8
推荐指数
1
解决办法
1988
查看次数

Protobuf-net与官方谷歌Protobuf for C++(消息编码)不兼容

我们在.NET中有一些(很多)类.我们使用protobuf-net来标记它们,并通过谷歌原始库为C++代码端生成.proto包装器.

所以我有一条消息(C++ DebugString()在一些EventBase类上(在.NET中EventCharacterMoved 继承,EventBase而在C++中我只是写入可选属性)):

UserId: -2792
EventCharacterMoved {
  Coordinates {
    Position {
      X: 196.41913
      Y: 130
      Z: 213
    }
    Rotation {
      X: 207
      Y: 130
      Z: 213
    }
  }
  OldCoordinates {
    Position {
      X: 196.41913
      Y: 130
      Z: 213
    }
    Rotation {
      X: 207
      Y: 130
      Z: 213
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

(来自这样的.proto文件)

message Coordinates {
   optional TreeFloat Position = 1;
   optional TreeFloat Rotation = 2;
}
message EventBase {
   optional int32 UserId = …
Run Code Online (Sandbox Code Playgroud)

.net c# c++ protocol-buffers protobuf-net

8
推荐指数
1
解决办法
2343
查看次数

protobuf-net如何序列化DateTime?

我正在开发一个包含Client/Server的项目.客户端是用Python编写的(将在linux上运行)和C#中的服务器.我正在通过标准套接字进行通信,我正在使用protobuf-net进行协议定义.但是,我想知道protobuf-net如何处理DateTime序列化.Unix日期时间与.net标准日期时间不同,那么我该如何处理这种情况呢?

谢谢

c# python protocol-buffers protobuf-net

8
推荐指数
1
解决办法
3179
查看次数

您如何在服务之间共享gRPC原型定义

我指定了许多独立的gRPC服务,这些服务都将在同一服务器进程中托管.每个服务都在自己的protobuf文件中定义.然后通过gRPC工具运行这些工具,为我提供目标语言(在我的情况下为c#),然后我可以在其中实现我的服务器和客户端.

每个这些不同的API使用一些共同的元素,诸如错误响应枚举,该消息类型(这似乎是在可用GRPC WellKnownTypes ;但我不能看我怎么有,要么让我定义我自己).

目前,我最终将每个proto构建重复的枚举和类放入他们自己的命名空间中.虽然我知道我可以在一个共同的原型文件中共享这些定义并包含它; 我不知道如何只将这些代码生成一个共同的命名空间.虽然这是有效的,但将它保持在一组是最整洁的; 如果在服务之间聚合错误等事情,它在转换和等效性方面也可能会出现问题.

我假设我遗漏了一些东西,因为我对WellKnownTypes命名空间这样的东西的阅读表明这应该是可能的,但如前所述,我也没有看到我在Proto中如何引用它.

因此目前在gRPC上似乎相当轻松,所以我的搜索量不会太多,我是新手,所以任何指针?

c# protocol-buffers protobuf-net grpc

8
推荐指数
1
解决办法
2816
查看次数