.Net - 从 System.Xml 到 Saxon.Api 性能问题

.Net - Moving from System.Xml to Saxon.Api performance issues

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

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

这非常有效,但我遇到了一个障碍,有时我会得到错误的数据,因为 XPathEvaluate 只支持 XPath 1.0 而我的语句是 XPath 2.0(问题发布 ).

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

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 倍。关于实现此解析器的方法的任何其他想法/想法?

这可能是您可以用它做的最好的事情 set-up。

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

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

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