简单数据结构的最轻序列化方法

Lightest serialization method for simple data structure

我有一个简单的数据结构,我想在不增加太多开销的情况下对其进行序列化。 就数据大小而言,您认为哪种方法最好?

我使用自定义序列化并以 # 作为分隔符,因为我 100% 确定我的数据中没有该字符。

数据结构示例:

string        Title       
int           ChapterIndex
List<String>  Paragraphs

我有上面object的列表

  1. 无优化(制表符和空格)

JSON:

[
 {
    "title": "some title 0",
    "chapterIndex": 0,
    "paragraphs": ["p1", "p2", "p3", "p4"]
 },
 {
    "title": "some title 1",
    "chapterIndex": 1,
    "paragraphs": ["p1chap1", "p2chap1", "p3chap1", "p4chap1"]
 }
]

XML:

<RootTag>
    <item title="some title 0" chapterIndex="0">
        <paragraph>p1</paragraph>
        <paragraph>p2</paragraph>
        <paragraph>p3</paragraph>
        <paragraph>p4</paragraph>
    </item>
    <item title="some title 1" chapterIndex="1">
        <paragraph>p1chap1</paragraph>
        <paragraph>p2chap1</paragraph>
        <paragraph>p3chap1</paragraph>
        <paragraph>p4chap1</paragraph>
    </item>
</RootTag>
  1. 优化(没有不必要的字符)

JSON:

[{"title":"some title 0","chapterIndex":0,"paragraphs":["p1","p2","p3","p4"]},{"title":"some title 1","chapterIndex":1,"paragraphs":["p1chap1","p2chap1","p3chap1","p4chap1"]}]

XML:

<RootTag><item title="some title 0" chapterIndex="0"><paragraph>p1</paragraph><paragraph>p2</paragraph><paragraph>p3</paragraph><paragraph>p4</paragraph></item><item title="some title 1" chapterIndex="1"><paragraph>p1chap1</paragraph><paragraph>p2chap1</paragraph><paragraph>p3chap1</paragraph><paragraph>p4chap1</paragraph></item></RootTag>

自定义:

some title 0##0##p1#p2#p3#p4###some title 1##1##p1chap1#p2chap1#p3chap1#p4chap1###and_so_on

自定义优化:

some title 0§0§p1#p2#p3#p4¤some title 1§1§p1chap1#p2chap1#p3chap1#p4chap1¤and_so_on

更新: 在我的例子中,我的字符串多于整数,因为它是一种 book/lyrics 应用程序,只需要标题 chapternumber/lyricId 和歌词的所有段落。

在我看来 JSON 是最简单的方法,而且不会产生任何开销。 在这里: http://json.org/example 你可以看到 JSON 和 XML 之间的区别。

JSON 解析器会自动为您完成所有工作。

我一直在我的项目中使用 google 的 proto-buf 序列化,它是迄今为止最轻量级的序列化之一。

决定起来很复杂。如果您的 类 主要由字符串组成,那么您的方法更好。唯一的 "more better" 方法是压缩生成的流(创建序列化数据后您仍然可以做的事情)。

如果你的数据主要是numeric/non-string,那么BinaryFormatter/protobuf是二进制序列化器,它们的输出应该比你的序列化器小,因为你使用5个字节来序列化10000,而二进制序列化程序可能只使用 2-4 个字节。

Json 和 xml 序列化器肯定会产生更大的序列化数据,因为它们都是 "textual" (因此它们将数字 10000 序列化为 10000 ) (和你的序列化程序一样) 它们包含额外的标记,这些标记是非空的,根据定义不小于单个字符。

现在...编写自定义序列化程序或使用 protobuf 哪个更好?我会说我更相信由 Marc Gravell (protobuf) 编写并基于 google 创建的 "standard" 的序列化程序,而不是我编写的序列化程序 :-) 因为现在你正在序列化整数和字符串……但也许明天您需要序列化 ​​DateTimefloat 或其他复杂类型。比正确实现序列化所需的时间少 100 个字节更好吗?由你来决定。

Protobuf 示例:

[ProtoContract]
public class MyObject
{
    [ProtoMember(1)]
    public string title { get; set; }
    [ProtoMember(2)]
    public int chapterIndex { get; set; }
    [ProtoMember(3)]
    public List<String> paragraphs { get; set; }
}

var myo = new[] 
{ 
    new MyObject
    {
        title = "some title 0",
        chapterIndex = 0,
        paragraphs = new List<string> { "p1", "p2", "p3", "p4" }
    }, 
    new MyObject
    {
        title = "some title 1",
        chapterIndex = 1,
        paragraphs = new List<string> { "p1chap1", "p2chap1", "p3chap1", "p4chap1" }
    }, 
};

byte[] bytes;

using (var ms = new MemoryStream())
{
    Serializer.Serialize(ms, myo);
    bytes = ms.ToArray();
}

using (var ms = new MemoryStream(bytes))
{
    MyObject[] myo2 = Serializer.Deserialize<MyObject[]>(ms);
}

byte[] 的长度是 86,因此只比您的自定义格式化程序 (81) 长一点。但请注意,这是单个数字字段,并且您使用的是单个数字。关键是 protobuf 可能仍然更好,因为它是由专业人士编写的,并且没有作为序列化程序的限制。

在尝试了答案中提供的所有序列化类型后,我找到了问题的答案。

当并且当要求是这些时:

  • 数据大小优先级
  • 简单的数据结构
  • 需要自定义序列化和反序列化
  • 了解数据内容以正确选择分隔符

只有在这些条件下才能使用自定义序列化,如我的问题所示。

关于性能?
这完全取决于您如何编写 de/serialization 方法。