如何加快大规模xml文件的反序列​​化速度

时间:2013-08-19 12:41:16

标签: .net xml performance io deserialization

我有大约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的部分有点薄。

任何建议都将不胜感激。

1 个答案:

答案 0 :(得分:3)

  

我需要为每条记录搜索这些记录以获得相对较少的数据,并将该数据保存到数据库中。

然后我建议你看XmlReader。 API非常繁琐,而且有点尴尬,它会让你进行一些混乱和调试以使其正确读取,但它会避免很多问题;特别是:

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

当然,对于 感兴趣的位,如果它不重要,你可能想要创建一个子树阅读器(它是一个XmlReader作用于特定的在父XmlReader}中的节点,并将 提供给XmlSerializer,将复杂的工作卸载到XmlSerializer(所以你只需要执行“下一个,下一个, next; decision-to-skip; next; decision-to-deserialize-via-sub-tree“等。)

但最终;你需要咀嚼所有那些IO,这需要一些时间。就个人而言,我会提出一个小小的旗帜也许,只是可能使用xml并不是最好的路线。是的,这就是你现在拥有的 ,但也许可以考虑启动一个项目,将未来的输出更改为更少的开销。