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

时间:2015-04-17 07:30:22

标签: c# xml json serialization xml-serialization

我有一个简单的数据结构,我想序列化而不会增加太多的开销。 您认为哪种方法在数据大小方面最好?

  • 使用分隔符作为“#”的自定义序列化/反序列化或我100%的其他字符在我的数据中不存在
  • XmlSerialization
  • JS​​ON
  • 其他

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

数据结构示例:

string        Title       
int           ChapterIndex
List<String>  Paragraphs

我有一个上面的对象列表

  1. 无优化(标签和空格)
  2. 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. 优化(没有不必要的字符)
    2. 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
      

      • ¤作为列表项分隔符
      • §作为项目分隔符内的属性
      • #作为段落内容分隔符

      更新 在我的情况下,我有字符串而不是整数,因为它是一种书籍/歌词应用程序,只需要标题chapternumber / lyricId和歌词的所有段落。

4 个答案:

答案 0 :(得分:3)

在尝试了答案中提供的所有序列化类型之后,我已经回答了我的问题。

何时和时,要求是:

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

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

关于表现?
这完全取决于你如何编写de /序列化方法。

答案 1 :(得分:2)

决定很复杂。如果你的课程主要由字符串组成,那么你的方法就更好了。唯一“更好”的方法是压缩生成的流(在创建序列化数据后仍可以执行的操作)。

如果您的数据主要是数字/非字符串,那么BinaryFormatter / protobuf是二进制序列化器,它们的输出应该小于序列化器,因为您使用5个字节来序列化{{1虽然二进制序列化器可能只使用2-4个字节。

Json和xml序列化程序肯定会产生更大的序列化数据,因为它们都是“文本的”(因此它们将数字10000序列化为10000)(与序列化程序一样)和< / em>它们包含非空的附加标记,根据定义,它不小于单个字符。

现在......编写自定义序列化程序或使用protobuf更好吗?我会说我会相信更多由Marc Gravell编写的序列化程序(protobuf)并基于谷歌创建的“标准”而不是我编写的序列化程序:-)因为现在你正在序列化整数和字符串..但也许明天你需要序列化10000DateTime或其他复杂类型。比正确实现序列化所需的小时数要少100个字节吗?是你必须决定它。

Protobuf的一个例子:

float

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

答案 2 :(得分:0)

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

JSON Parser会自动为您完成所有事情。

答案 3 :(得分:0)

我一直在我的项目中使用谷歌的proto-buf序列化,而且它是迄今为止最轻的之一。