protobuf-net 与 protobuf-csharp-port 的性能对比

Posted

技术标签:

【中文标题】protobuf-net 与 protobuf-csharp-port 的性能对比【英文标题】:Performance of protobuf-net vs. protobuf-csharp-port 【发布时间】:2011-04-19 20:18:56 【问题描述】:

我知道这两个库的功能和设计,但我没有发现这两个库之间有任何直接的性能比较。两者都绝对是很棒的库。关于设计,我认为 protobuf-csharp-port 由于反射较少,应该稍微快一些,对吧?

此外:

protobuf-net V2 什么时候发布?有什么计划吗,马克? 会有新版本的 protobuf-csharp-port 吗,Jon?

谢谢。

【问题讨论】:

【参考方案1】:

重新性能; protobuf-net 旨在尽可能少地执行该反射,然后创建高效的数据访问代码。在 v2 中,它在许多方面更进一步 - 使用 much 较低级别的元编程,以及 如果你想要它(完全可选),预生成独立的序列化程序 dll - 因此在运行时反射成本介于最小(如果使用运行时元编程)到零(如果使用预生成)之间。

重新发布; “什么时候准备好”;生活是疯狂的忙碌,但一个 alpha dll 可用于完整的 .NET 和 iPhone(后者可能适用于大多数较轻的运行时,因为 iPhone 是最受限制的)。最终,现实是(如无赞助等)它会稍微落后于工作和家庭之类的事情——不过,我会尽量抽出时间。

我认为更合理的比较是目标; protobuf-net 旨在轻松安装到您现有的 DTO 或域模型中,无需大量返工 - 或用于代码优先场景。它还支持从 .proto 生成,但这不是主要目标(但当然是非常可取的)。它还支持一个非常不同的 API,面向常见的 .NET 隐喻,而不是常见的 protobuf 隐喻。

或者换一种说法:

protobuf-csharp-port 专注于 protobuf,并将 C# / .NET 添加到现有的 protobuf 格局中 protobuf-net 专注于 C#/.NET,并将 protobuf 添加到现有的 C#/.NET 格局中

一个微妙的区别,也许 - 并且确实可以为 .NET 提供一个有价值的序列化 API。

因此,如果您的主要目标是在您在同一团队中积极工作的异构环境之间进行互操作 - 那么 protobuf-csharp-port 可能更适合您。

我也有点...“松散”与 protobuf,所以我没有(嗯,最小的)内疚超出标准规范(同时保持在协议定义内)以鞋拔继承,完整-graphs 等 - 在 .NET 生态系统中很常见,但在 protobuf 中没有直接映射。当然,我可以更多地研究 WCF 之类的工具(以及在较小程度上:远程处理)。

【讨论】:

哇!感谢您提供这个详细的答案(一如既往 - 关于我读到的关于 protobuf-net 的最后 50 篇文章)。正如我所说,我知道这两个项目的理念,事实上,我想使用两者之一的场景是将 Silverlight 客户端集成到现有的 protobuf 环境中:.proto first --> java (client+server incl.xml /json 格式化程序),c#,...但是,我可以同时使用这两个库(当前版本)。但我真正感兴趣的是性能比较——即使只有几毫秒。我说得对吗,protobuf-csharp-port(理论上)不能比 protobuf-net 慢? @Stephan 他们很可能是同一个球场;取决于编码的实现方式可能会导致任一方向的差异。然而,在这两种情况下,真正的瓶颈是带宽(磁盘或网络)。两者在电线上应该几乎相同。简而言之,两者都不是“明显”更快或更慢。不过,请随意介绍。 好的 Marc,感谢您的回答以及您为 protobuf-net 付出的所有努力。【参考方案2】:

当我使用 protobuf-csharp-port 时,我在这个库中发现了一个错误。 例如,当我创建这样的消息时:

    message CalculateInfo
    required string CalStarttime=1;
    optional string CalEndtime=2;
    required string Smiles=3;
    optional string CAS=4;
    optional string ChName=5;
    optional string EnName=6;
    required string Param=7;
    required bytes Result=8;
    required bool IsFinished=9;


    message GetAllCalulateResponse
        required bool  isSuccessful = 1;
        required int32 Count=2;
        repeated CalculateInfo History=3;

    

这样的代码(在python中):

msg_resp.Count = len(resultSets)

calculateInfo = [None] * msg_resp.Count
cnt = 0
for result in resultSets:
    calculateInfo[cnt] = msg_resp.History.add()
    calculateInfo[cnt].CalStarttime = str(result.calculateStartTime)
    calculateInfo[cnt].CalEndtime = result.calculateEndTime.strftime('%Y-%m-%d %X')
    calculateInfo[cnt].IsFinished = result.isFinished
    calculateInfo[cnt].Param = result.paramInfo
    calculateInfo[cnt].Result = str('ff'*1000) #result.result

    calculateInfo[cnt].Smiles = result.smilesInfo.smilesInfo
    calculateInfo[cnt].CAS = result.smilesInfo.casInfo

    nameSets = CompoundName.objects.filter(simlesInfo=result.smilesInfo.pk,isDefault=True)
    for nameSet in nameSets:
        if nameSet.languageID.languageStr == Chinese_Name_Label:
            calculateInfo[cnt].ChName = nameSet.nameStr 
        elif nameSet.languageID.languageStr == English_Name_Label:
            calculateInfo[cnt].EnName = nameSet.nameStr

    cnt = cnt +1 

C#代码会出现这个错误: 解析协议消息时,输入意外在字段中间结束。这可能意味着输入被截断或嵌入的消息误报了自己的长度。

当我对 calculateInfo[cnt].Result 进行小操作时,它又可以工作了。

【讨论】:

以上是关于protobuf-net 与 protobuf-csharp-port 的性能对比的主要内容,如果未能解决你的问题,请参考以下文章

在 protobuf-c 中表示指针变量

如何使用 mingw 在 Windows 中构建 protobuf-c?

如何序列化/反序列化 protobuf-c 中的枚举

为 mbed LPC1768 arm-none-eabi-g++ 构建 protobuf-c、libprotobuf-c

无法让 Protobuf-net 与 vb.net 一起使用

与 protobuf-net 和 C# 的接口