我有一大类大约90个变量,比如:
[Serializable]
[ProtoContract]
public class myLargeClass
{
[ProtoMember(1)]
public int BetId { get; set; }
...
[ProtoMember(95)]
public string someVariable { get; set; }
}
我有大量这样的对象保存到磁盘中,用于我的应用程序。这是使用protobuf序列化到一个大列表中的,并放在我的本地磁盘上。
List<myLargeClass>
我的想法是,我没有将整个东西反序列化到大类中,而是制作了一个更简单的版本,只包含变量的一个子集。还有序列化的大对象的byte[],这样我就可以在需要的情况下访问所有变量:
[Serializable]
[ProtoContract]
public class mySmallerClass
{
[ProtoMember(1)]
public int Id { get; set; }
...
[ProtoMember(10)]
public bool someVariable { get; set; }
public byte[] largeObject { get; set; }
}
我目前的解决方案很慢,因为我将两者串行化为小型和大型类:
var smallObjects = Serializer.Deserialize<List<mySmallerClass>>(data);
var largeObjects = Serializer.Deserialize<List<myLargeClass>>(data);
Parallel.ForEach(smallObjects, (object) =>
{
var x = largeObjects.Where(b => b.Id == object.Id).Single();
object.largeObject = Crypto.Serialize(x);
});
这种解决方案非常缓慢,尤其是当您有几十万或数百万个对象时。
如何有效地将大对象序列化为小对象?
据此:
我有大量的这些对象
您在List
中进行了大量查找,这就是O(n)
的复杂性。将List
转换为Dictionary
,然后通过Id
:获取对象
var largeObjects = Serializer.Deserialize<List<myLargeClass>>(data).ToDictionary(x => x.Id, x => x);
...
var x = largeObjects[object.Id];
如果你只想要小数据,那么mySmallerClass
不需要额外的blob字段就可以了。然而,如果你需要能够"往返"你不跟踪的字段:
[ProtoContract]
public class mySmallerClass : Extensible
{
...
}
还要注意,protobuf-net并不寻找或关心[Serializable]
。