如何在 protobuf-net 中启用字符串实习?

Posted

技术标签:

【中文标题】如何在 protobuf-net 中启用字符串实习?【英文标题】:how do I enable string interning in protobuf-net? 【发布时间】:2011-06-24 04:41:30 【问题描述】:

我正在使用 v2 rev 421。 当我保存 protobuf-net 生成的流并通过字符串实用程序将其放入时,它发现了许多重复的字符串。我说的是应用产生的字符串,可以interned,但是string interning好像默认没有开启。

如何启用它?

谢谢。

【问题讨论】:

【参考方案1】:

这里有两种不同类型的实习; 在反序列化时有实习 - 这始终处于启用状态,因此如果 data 中有重复项,您应该只会在托管类中看到一个 .NET string 实例,重新- 根据需要多次使用。

3.x 更新 默认情况下不再启用字符串驻留。要启用它,请在您的模型中设置以下内容。

RuntimeTypeModel.Default.InternStrings = true;

在序列化时也有实习,以避免在序列化时将数据复制到流中。这是 not 默认开启的,原因很简单,protobuf 规范中没有定义此类行为; protobuf-net 默认尝试保持在规范内,仅在选择加入的基础上使用扩展。

如果您想为 protobuf-net=to=protobuf-net 使用启用此功能,请为任何给定字符串启用 AsReference 选项:

[ProtoMember(13, AsReference = true)]
public string Foo  get; set; 

这使用 protobuf-net 特定于实现的表示。但是,对于互操作目的,它不会很好地发挥作用。如果您需要以可互操作的方式进行此操作,唯一要做的就是单独存储列表(可能在某个List<string> 中),并在数据中使用列表中的位置,即 p>

// this is .... uglier, but probably easier if you need cross-platform
public int FooOffset 
    get  return Foos.IndexOf(Foo); 
    set  Foo = Foos[value]; 

【讨论】:

谢谢。有一点我不明白。即使它是 protobuf-net 特定的功能,它产生的协议缓冲区流仍然是有效的流,对吗?而且您仍然可以创建相应的 .proto 规范 - 如果我是正确的,这仍然需要移植到 v2。那我很好奇,没有 AsReference 的 .proto 和有 AsReference 的 .proto 有什么区别。 这将是经典string foo = 13netObject foo = 13 之间的区别,其中netObject 是具有一些属性的单独消息类型;在这种情况下,重要的是int existingKey = 1、int newKey = 2` 和bytes payload = 10;将发送一个带有“2=>some unique number, 10=>the string”的新字符串;重复的字符串将与“1=>我们之前想到的数字”一起发送 将相关代码移植到 v2 后,检查相应的 .proto 文件会非常有趣。 好的,我有一个问题。我如何使用模型来做到这一点?问题是我的代理被归于 DataContract/DataMember 并且我不引用 protobuf-net,除非在负责(反)序列化的唯一程序集中。 @Mark 它应该是 ValueMember 上的 AsReference

以上是关于如何在 protobuf-net 中启用字符串实习?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Protobuf-net 中动态添加 Proto 成员

如何在 xamarin ios pcl 中使用 protobuf-net

如何在 VB.NET 中使用 protobuf-net 添加枚举?

如何在 Protobuf-Net 中保留一个可为空值的数组?

Protobuf-net:如何调试“不支持嵌套或锯齿状列表和数组”

如何使用 protobuf-net 读回附加的对象?