如何在 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 = 13
与netObject 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 中保留一个可为空值的数组?