【问题标题】:Protobuf-net IsPacked=true for user defined structuresProtobuf-net IsPacked=true 用于用户定义的结构
【发布时间】:2013-04-16 18:46:51
【问题描述】:

目前是否可以将 IsPacked=true 用于用户定义的结构?如果没有,那以后有计划吗?

当我尝试将该属性应用于 ColorBGRA8[] 类型的字段时,出现以下异常:System.InvalidOperationException:只有简单的数据类型可以使用打包编码

我的场景如下:我正在编写一个游戏,并且有大量用于各种事物的 blitable 结构,例如颜色、向量、矩阵、顶点、常量缓冲区。它们的内存布局需要在编译时精确定义,以匹配着色器中的常量缓冲区布局(通常在哪里?需要在 16 字节边界上对齐)。

我不想浪费任何人的时间,但我找不到有关此特定问题的任何最新信息。

回答后编辑

我目前正在测试一种解决方案,该解决方案几乎将 protobuf-net 用于除用户定义的大型数组之外的所有内容,但可以使用 blitable 结构。我所有的自定义结构数组字段都已替换为可以打包的字节数组。在 protobuf-net 完成数据反序列化后,我通过 p/invoke 使用 memcpy 以便能够再次使用自定义结构数组。

以下数字来自对一个实例进行序列化的测试,该实例包含 byte[] 或 ColorBGRA8[] 的一个字段。 raw 测试数据约为 38MiB 的数据,例如颜色数组中有 1000000 个条目。序列化是使用 MemoryStream 在内存中的一种。

写作
Platform.Copy + Protobuf:51ms,大小:38,15 MiB
Protobuf:2093ms,大小:109,45 MiB

阅读
Platform.Copy + Protobuf:43ms Protobuf:2307ms

测试表明,对于 巨大 或多或少随机数据的数组,可能会出现明显的内存开销。如果不是(反)序列化时间,这不会有什么大不了的。我知道 protobuf-net 可能不是为我的极端情况设计的,更不用说针对它进行优化了,但这是我不愿意接受的。

我想我会坚持使用这种混合方法,因为 protobuf-net 对其他一切都非常有效。

【问题讨论】:

    标签: c# protobuf-net


    【解决方案1】:

    简单地说“不适用”。引用encoding specification:

    只有原始数字类型(使用 varint、32 位或 64 位有线类型的类型)的重复字段才能声明为“打包”。

    这不适用于自定义结构或类。此处适用的两种方法是字符串(以长度为前缀)和组(开始/结束标记)。后者的编码通常更便宜,但 Google 更喜欢前者。

    Protobuf 并非旨在任意匹配某些其他字节布局。它是自己的编码格式,仅用于处理/输出 protobuf 数据。这就像说“我正在编写 XML,但我希望它看起来像 {non-xml}”。

    【讨论】:

    • 感谢您的快速回答以及不支持的原因。这样就搞定了。
    猜你喜欢
    • 2022-10-14
    • 2013-05-31
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2011-10-26
    • 1970-01-01
    相关资源
    最近更新 更多