【问题标题】:How do I speed up deserialization of massive xml files如何加快海量xml文件的反序列​​化
【发布时间】:2013-08-21 06:20:58
【问题描述】:

我有大约 2600 个大型 xml 文件(解压缩时每个大约 1gb),这些文件目前被非常密集地压缩并存储在我的 SSD 上。这些文件每个包含 23000 到 30000 条记录。

我需要为每条记录保留相对少量的数据,并将这些数据保存到数据库中。

我估计(通过一些基本测试)这将需要至少 150 小时来进行抓取(我假设持久性会很快,因为它的数据要少得多)。

我对 .NET 的 IO 方法以及如何提高它们的效率不是很熟悉,所以这里是我目前用来测试的方法:

 public PCCompounds DoStuff(String file)
    {
        using(FileStream fs = this.LoadFile(file))
        {
            using (GZipStream gz = this.Unzip(fs))
            {
                using (XmlReader xml = this.OpenFile(gz))
                {
                    return (PCCompounds)this.ParseXMLEntity(xml);
                }
            }
        }
    }

    private FileStream LoadFile(String file)
    {
        return new FileStream(file, FileMode.Open);
    }

    private GZipStream Unzip(FileStream file)
    {
        return new GZipStream(file, CompressionMode.Decompress);
    }

    private XmlReader OpenFile(GZipStream file)
    {
        return XmlReader.Create(file);
    }

    private Object ParseXMLEntity(XmlReader xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(PCCompounds));

        return serializer.Deserialize(xml);
    }

不幸的是,我只在 stackoverflow 上找到了this,而且大多数答案都有些不完整。我也看过 Sasha Goldstein 的 .NET 性能书籍,但他关于磁盘 IO 的部分有点薄。

任何建议将不胜感激。

【问题讨论】:

  • XML 的“反序列化”通常称为解析。 FWIW,我认为 1Gb/分钟的解析速度实际上是可以实现的,比这更快的任何东西都将具有挑战性。

标签: .net xml performance io deserialization


【解决方案1】:

我需要为每条记录保留相对少量的数据,并将这些数据保存到数据库中。

那我建议你看看XmlReader。 API 非常繁琐,而且有点笨拙,您需要进行一些混乱和调试才能使其正确阅读,但会避免很多问题;特别是:

  • 当您知道自己对子树不感兴趣时​​,可以跳过它们
  • 你没有实例化你不需要的对象

当然,对于您感兴趣的位,如果它不重要,您可能需要创建一个子树阅读器(这是一个XmlReader,作用域为一个父 XmlReader),并将 那个 提供给 XmlSerializer,将复杂的工作卸载到 XmlSerializer(所以你只需执行“下一个,下一个,下一个;决定跳过;下一个;决定通过子树反序列化”等)。

不过,最终;您将需要仔细研究所有的 IO,这需要一些时间。就个人而言,我会提出一个小标志,也许,只是也许使用 xml 并不是最好的前进路线。是的,这是您现在所拥有的,但也许可以考虑启动一个项目以将未来的输出更改为开销较小的东西。

【讨论】:

  • 谢谢。我正在使用 XmlReader(如上面的代码所示),但我显然是在天真地使用它。我会看看你建议的这个子树阅读器概念。不过,这些数据来自外部来源,因此虽然并不理想,但它比学习专门针对化学的全新文本分隔格式要好。
  • @dansan 不,我是说“使用XmlReader 直到你知道你想要数据”,甚至可以用XmlReader 读取所有数据(而不是使用XmlSerializer 完全,除非数据很复杂)。创建XmlReader 并将整个内容传递给XmlSerializer 并不是我的意思。
  • 哦,我明白了。我误解了。感谢您的澄清。
猜你喜欢
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
相关资源
最近更新 更多