我的问题与此问题中的问题非常相似:protobuf-net concurrent performance issue in TakeLock。不同的是,在我们的例子中,我们使用CompressedSerializer和反序列化数据。每次我们需要反序列化数据时,都会从8个不同的线程(在8核CPU上)调用以下代码。
var result = new ProtoCompressedSerializer().Deserialize<Dictionary<string, CustomStruct>>(...)
以下是ANTS Performance Profiler的结果:
图中的第一个节点是我们使用上面的代码调用反序列化的方法。每个框中左侧的数字是以秒为单位的时间,右侧是命中计数。正如您所看到的,RunTimeTypeModel.TakeLock花费了大量时间。在上面的链接问题中,建议是预编译模型。这可能是CompressedSerializer及其反序列化方法吗?从性能角度来看,创建一个序列化程序并在所有线程中共享它更好吗?它是线程安全的吗?
答案 0 :(得分:0)
在尝试了几个选项并使用Performance Profilers比较它们的性能之后,我得出的结论是Dictionary<T,K>
未被ProtoBuf-net正确支持,甚至预先初始化序列化器也不会有帮助
解决方案是将Dictionary包装成一个新类作为唯一的数据成员。这不仅可以提高性能几倍,我们看到了3倍的改进,而且几乎消除了TakeLock的使用和相关的超时问题。
示例:
[Serializable]
[ProtoContract]
[DataContract]
public class ModelADict
{
[ProtoMember(1)]
[DataMember]
public Dictionary<string, ModelA> sub { get; set; }
public ModelADict()
{
sub = new Dictionary<string, ModelA>();
}
}