【问题标题】:.Net - Moving from System.Xml to Saxon.Api performance issues.Net - 从 System.Xml 迁移到 Saxon.Api 性能问题
【发布时间】:2018-03-13 17:42:39
【问题描述】:

我编写了一个 C# 应用程序来解析非常大 (100MB+) 的 XML 文件。

我完成它的方法是使用System.Xml.XmlReader 遍历文件,然后,一旦到达需要从中收集值的最终节点,我将每个非常小的元素转换为System.Xml.Linq.XElement并通过XEelement.XPathEvaluate 执行各种XPath 语句来获取我需要的数据。

这工作得非常好且高效,但我遇到了一个问题,有时我会收到错误的数据,因为XPathEvaluate 仅支持 XPath 1.0 而我的声明是 XPath 2.0(问题已发布here)。

我最初执行此操作的代码如下所示:

void parseNode_Old(XmlReader rdr, List<string> xPathsToExtract)
{
    // Enter the node:
    rdr.Read();

    // Load it as an XElement so as to be able to evaluate XPaths:
    var nd = XElement.Load(rdr);

    // Loop through the XPaths related to that node and evaluate them:
    foreach (var xPath in xPathsToExtract)
    {
        var xPathVal = nd.XPathEvaluate(xPath);

        // Do whatever with the extracted value(s)
    }
}

按照我上一个问题中给出的建议,我决定最好的解决方案是从 System.Xml 移动到 Saxon.Api(它确实支持 XPath 2.0),我当前更新的代码如下所示:

void parseNode_Saxon(XmlReader rdr, List<string> xPathsToExtract)
{
    // Set up the Saxon XPath processors:
    Processor processor = new Processor(false);
    XPathCompiler compiler = processor.NewXPathCompiler();
    XdmNode nd = processor.NewDocumentBuilder().Build(rdr);

    // Loop through the XPaths related to that node and evaluate them:
    foreach (var xPath in xPathsToExtract)
    {
        var xPathVal = compiler.EvaluateSingle(xPath, (XdmNode)childNode);

        // Do whatever with the extracted value(s)
    }
}

这是可行的(对我的 XPath 进行了一些其他更改),但它变得慢了大约 5-10 倍。

这是我第一次使用 Saxon.Api 库,这也是我想出的。我希望有更好的方法来实现这一点,以使代码执行速度具有可比性,或者,如果有人对如何以更好的方式评估 XPath 2.0 语句而无需大量重写有其他想法,我很想听听他们!

任何帮助将不胜感激!

谢谢!!

更新:

在尝试自己解决此问题时,我将以下 2 条语句移至构造函数:

Processor processor = new Processor(false);
XPathCompiler compiler = processor.NewXPathCompiler();

而不是在每次调用此方法时不断地重新创建它们,这有很大帮助,但该过程仍然比本机 System.Xml.Linq 版本慢约 3 倍。关于如何实现这个解析器的任何其他想法/想法?

【问题讨论】:

    标签: c# xml xpath xml-parsing saxon


    【解决方案1】:

    这可能是您使用此设置所能做的最好的事情。

    .NET 上的 Saxon 通常比 Java 上的 Saxon 慢 3-5 倍,原因我们从未深入了解。我们目前正在探索使用 Excelsior JET 而不是 IKVMC 重建它的可能性,看看这是否可以加快速度。

    Saxon 在第三方 DOM 实现上比在其自己的本机树表示上慢得多,但您似乎已更改代码以使用本机树模型。

    由于每次执行 XPath 表达式时都要对其进行解析,因此 XPath 编译时间可能会主导性能(即使您正在搜索大型 XML 文档)。直到最近,Saxon 的编译时性能还很少受到关注,因为我们认为在编译时做更多的工作以节省运行时的工作量总是值得的。但在这种情况下,显然情况并非如此。将编译和运行时分开并分别测量可能是值得的,只是看看这是否能提供任何见解。例如,它可能会建议关闭一些优化选项。显然,如果您可以缓存和重用已编译的 XPath 表达式,那将有所帮助。

    【讨论】:

    • 非常感谢,迈克尔,我希望我的编码中出现了一个小故障……真可惜,因为它是一个可以使用的深度库。不过,对于这个特定的项目,使用不同的项目可能最有意义。又是坦克!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2020-08-21
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    相关资源
    最近更新 更多