Альтернатива Protobuf для размера
Недавно я взял на себя задачу, где было предложено использовать Protobuf для сериализации объекта, который должен быть записан в виде строки base64. На данный момент это будет protobuf-net для порта.NET. Предыдущие методы хранения этих данных были серией битовых маскировок, но они были переросшими, и это был предложенный маршрут. К сожалению, данные, записанные с помощью этого подхода, просто слишком велики для моих целей.
В коде объект, который я сериализую, выглядит следующим образом. Я пробовал использовать как украшенные POCO, так и сгенерированные классы ProtoGen. Созданные ProtoGen классы фактически сериализуются в менее оптимизированные данные.
Obj
- Time
- List of an objects. A pair is what must be recorded.
Pair = [Key | Time]
Глядя на вывод и то, как размер увеличивается с ростом длины списка, я думаю, что часть размера исходит от хранения информации о типе класса. Я попытался понять, как это будет с хранением пар в параллельных массивах и использованием "Packed", однако я не вижу значительного улучшения размера. Может быть, 10%-15%. В нынешнем виде это на порядок больше, чем в предыдущем методе хранения данных, однако этот старый метод не будет работать, так как у нас заканчивается свободное пространство.
Мой вопрос заключается в том, что помимо простого увеличения пространства ключей путем добавления еще нескольких бит здесь, в старом методе, есть ли способ оптимизировать Protobuf для размера, который я могу пропустить? Или, возможно, альтернатива для сериализации довольно простых объектов, оптимизированных по размеру?
Я еще не пробовал, но из того, что я читаю, даже сжатие текущих данных вернуло бы лишь незначительные улучшения. Я буду жать это как вариант дальше.
Образец класса:
[ProtoContract]
public class Foo : BaseOfFoo
{
[ProtoMember(1)]
public UInt32 Time { get; set; }
[ProtoMember(2)]
public List<ValuePair> KeywordValues { get; private set; }
}
[Serializable]
[ProtoContract]
public class ValuePair
{
[ProtoMember(1)]
public UInt32 Id { get; set; }
[ProtoMember(2)]
public UInt32 Time { get; set; }
}