我目前正在使用Saxon在我们的.NET应用程序中处理Xquery。我们正在使用非常大的XML文件(~2GB)。当使用Saxon二进制文件直接对其中一个文件运行Xquery时,完成评估所花费的时间大约是2分钟,但是当我从C#应用程序进行评估时,经过的时间增加到大约10分钟,而且我没有&然而,我能够识别出我做错了什么。
这是我在使用Saxon二进制文件运行Xquery时所做的事情 通过命令行:
Query.exe -config:config.xml -q:XQueryTest.txt
这些是config.xml
:
<configuration xmlns="http://saxon.sf.net/ns/configuration" edition="HE">
<xquery defaultElementNamespace="http://www.irs.gov/efile"/>
</configuration>
XQueryTest.txt
包含我们要处理的Xquery。从命令行运行Xquery时,我们使用doc()
函数修改它以指示我们将对其运行的文件。以下是一个示例行:
for
$ReturnData at $currentReturnDataPos in if(exists(doc("2GB.XML")/Return/ReturnData)) then doc("2GB.XML")/Return/ReturnData else element{'ReturnData'} {''}
如上所述,运行此命令大约需要2分钟才能完成。
现在,我正在.NET应用程序中进行这些评估。
Processor processor = new Processor();
DocumentBuilder documentBuilder = processor.NewDocumentBuilder();
documentBuilder.IsLineNumbering = true;
documentBuilder.WhitespacePolicy = WhitespacePolicy.PreserveAll;
XQueryCompiler compiler = processor.NewXQueryCompiler();
string query = BuildXqueryString();
if (!String.IsNullOrEmpty(query))
{
XQueryExecutable executable = compiler.Compile(query);
XQueryEvaluator evaluator = executable.Load();
using (XmlReader myReader = XmlReader.Create(@"C:\Users\Administrator\Desktop\2GB.xml"))
{
evaluator.ContextItem = documentBuilder.Build(myReader);
}
var evaluations = evaluator.Evaluate();
}
我们遇到的问题是:evaluator.ContextItem = documentBuilder.Build(myReader)
。哪个甚至不是评估,而只是加载文件。这条线需要花费太多时间来执行,我需要知道这是否是预期的,或者是否有提高速度的方法。我已经使用了Build()
方法的所有不同重载,它们都需要花费很多时间才能完成,这比从命令行执行时执行的时间要长得多。
关于使用Saxon的流容量按部分读取文件,由于我们生成的Xqueries,这不是一个选项,因为Xquery可以在XML的任何部分组合信息。
答案 0 :(得分:1)
在某些情况下,我们已经看到Java平台上的Saxon与.NET平台上的Saxon之间存在类似的5:1比率,尽管进行了大量调查,但我们还没有找到原因。部分原因是它似乎不一致。当我们首次使用IKVMC交叉编译器在.NET上运行Saxon时,这个比例要好得多,只有大约25%的开销,但从那时起技术上似乎发生了一些变化:Java VMs变得更快,IKVMC已经从使用GNU Classpath库切换到OpenJDK,而.NET本身并没有停滞不前。
但是,对我来说,新的一点是,相同的代码应该从.NET命令行运行得比从.NET API运行得快得多。这里最大的区别是,当您从命令行运行时,Saxon使用Apache Xerces解析器(使用IKVMC转换为.NET代码)构建文档,而当您按照所示方式使用DocumentBuilder.build()时,您正在使用Microsoft的XmlReader。
我希望在提供(文件系统)URI时文档构建运行得最快,但我不能说我已经测量过了。可能值得做一些实验(可能使用较小的文件)并向我们展示结果。或者,您是否尝试过使用应用程序中的doc()方法,而不是先构建文档?
答案 1 :(得分:0)
使用.NET XmlReader进行解析会导致性能下降。使用.NET XML解析器和Saxon接收器进行Push / Pull SAX事件处理要比使用Saxon中提供的JAXP xerces解析器慢得多。
要强制执行JAXP解析器,您可以执行以下操作:
evaluator.ContextItem = documentBuilder.Build(new Uri(&#34; file:/// C:\ Users \ Administrator \ Desktop \ 2GB.xml&#34;));