【问题标题】:Quick and dirty reflection based XML Serializer基于快速和肮脏反射的 XML 序列化器
【发布时间】:2009-12-01 02:18:36
【问题描述】:

有谁知道基于反射的 XML 序列化器的快速而肮脏的实现?

由于可怕的启动时间,我希望删除我的 XML 序列化代码。 我知道 sgen.exe,但不想让我的构建和打包过程复杂化。

我们在启动时使用 XML 序列化从文件中提取配置值,反射命中将是最小的,我们正在谈论最多 20-40 个值。我们在这里不需要任何超快的东西。我只是不想因为编译在我的情况下似乎是 500-700ms 的 XML 序列化程序而受到打击。

我也想要控制代码,因为我想要非常健壮的错误处理。

我知道 protobuf.net,但它可能有点矫枉过正。看看数据合约,它们可能有点有限,需要大量的装饰,我想避免。

【问题讨论】:

    标签: c# .net serialization xml-serialization


    【解决方案1】:

    如果只是 20 到 40 个值,为什么不扔掉所有的序列化问题并手动编码呢?您应该能够立即编写设置阅读课程。哎呀,你可以用代码生成它并早点回家。这样一来,它就可以随心所欲地处理错误,并且卸载速度将超过 700 毫秒。

    【讨论】:

    • 我同意。如果您完全关心执行速度,那么使用反射似乎是一条糟糕的道路。
    • 反射在我的情况下并没有那么大的影响,它花了我 63 毫秒来加载 dom(前向解析是一个更快的路线......但可能不值得努力)和 17 毫秒用反射加载我的字段,我还没有完成优化。
    【解决方案2】:

    您是否尝试过使用 sgen 预编译序列化程序?

    http://blog.lab49.com/archives/2358

    【讨论】:

    • sorry 并不是说​​听起来粗鲁,但 sgen 完全不可能。
    【解决方案3】:

    如果您使用带有 /k[eep] 选项的 sgen.exe,它将保留生成的 C# 源代码,然后您可以将其集成到您的项目中。您可以根据需要对其进行自定义。

    编辑:换句话说,你使用 sgen 不是作为预编译器(你说你不能这样做),而是作为代码生成器。

    【讨论】:

      【解决方案4】:

      I wrote my own... 如果有人在 BSD 许可下有类似规范的代码,请随意使用它。

      这里有一些示例测试,它生成可爱的 XML 就像 XML 序列化器一样,只是在 sgen 不是选项的配置文件场景中更快:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.IO;
      using NUnit.Framework;
      using MediaBrowser.Library.Persistance;
      
      namespace TestMediaBrowser.Unit {
          [TestFixture]
          public class TestXmlSettings {
      
              enum Farts { 
                  Smelly, 
                  SilentButDeadly
              }
      
              class Monster {
                  public Weapon Weapon; 
              }
      
              class Weapon {
                  public int LaserCount { get; set; }
              }
      
              class Farter {
                  public Farts Smell = Farts.Smelly;
              }
      
              class Group {
                  public List<Person> People;
              }
      
              class Person {
                  public int Age = 1; 
                  public string Name = "Default";
                  public bool Happy = true;
                  public DateTime Birthdate = DateTime.Now;  
              }
      
              class Account {
                  public Person Person;
                  public int Balance;
              }
      
              const string CONFIG_FILE = "test.config";
      
              private void ClearConfig() {
                  if (File.Exists(CONFIG_FILE)) {
                      File.Delete(CONFIG_FILE);
                  }
              }
      
              public void TestProperty() {
                  ClearConfig();
                  Monster monster = new Monster();
                  XmlSettings<Monster> settings = XmlSettings<Monster>.Bind(monster, CONFIG_FILE);
                  monster.Weapon = new Weapon();
                  monster.Weapon.LaserCount = 99;
                  settings.Write();
      
                  monster = new Monster();
                  settings = XmlSettings<Monster>.Bind(monster, CONFIG_FILE);
      
                  Assert.AreEqual(monster.Weapon.LaserCount, 99);
              } 
      
              public void TestEnum() {
                  ClearConfig();
                  Farter farter = new Farter();
                  XmlSettings<Farter> settings = XmlSettings<Farter>.Bind(farter, CONFIG_FILE);
                  farter.Smell = Farts.SilentButDeadly;
                  settings.Write();
      
                  farter = new Farter();
                  settings = XmlSettings<Farter>.Bind(farter, CONFIG_FILE);
      
                  Assert.AreEqual(farter.Smell, Farts.SilentButDeadly);
              } 
      
              [Test]
              public void TestList() {
                  ClearConfig();
                  Group group = new Group();
                  group.People = new List<Person>();
                  group.People.Add(new Person());
                  group.People.Add(new Person());
                  XmlSettings<Group> settings = XmlSettings<Group>.Bind(group, CONFIG_FILE);
                  settings.Write();
      
                  group = new Group();
                  settings = XmlSettings<Group>.Bind(group, CONFIG_FILE);
      
                  Assert.AreEqual(group.People.Count, 2);
      
              }
      
              [Test]
              public void BasicValueTypeTest() {
                  ClearConfig();
                  var person = new Person();
                  XmlSettings<Person> settings = XmlSettings<Person>.Bind(person, CONFIG_FILE);
                  person.Age = 3;
                  person.Name = "Sam";
                  person.Happy = false;
                  person.Birthdate = DateTime.Today;
                  settings.Write();
      
                  person = new Person();
                  settings = XmlSettings<Person>.Bind(person, CONFIG_FILE);
      
                  Assert.AreEqual(person.Age, 3);
                  Assert.AreEqual(person.Name, "Sam");
                  Assert.AreEqual(person.Happy, false);
                  Assert.AreEqual(person.Birthdate, DateTime.Today);
              }
      
              [Test]
              public void NestedObjectTypeTest() {
                  ClearConfig();
                  var account = new Account();
                  var settings = XmlSettings<Account>.Bind(account, CONFIG_FILE);
                  var person = new Person();
                  person.Age = 3;
                  person.Name = "Sam";
                  person.Happy = false;
                  person.Birthdate = DateTime.Today;
      
                  account.Person = person;
                  account.Balance = 999;
      
                  settings.Write();
      
                  account = new Account();
                  settings = XmlSettings<Account>.Bind(account, CONFIG_FILE);
      
      
                  person = account.Person;
                  Assert.AreEqual(account.Balance, 999);
                  Assert.AreEqual(person.Age, 3);
                  Assert.AreEqual(person.Name, "Sam"); 
                  Assert.AreEqual(person.Happy, false); 
                  Assert.AreEqual(person.Birthdate, DateTime.Today); 
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-08
        • 1970-01-01
        • 2015-11-24
        • 2012-12-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多