在 C# 中将序列化对象及其更简单的变体一起存储



我有一大类大约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]

相关内容

最新更新