2016-04-28 21 views
1

我目前在我们的.NET应用程序中使用Saxon来处理Xquery。我们正在处理非常大的XML文件(〜2GB)。当对直接使用Saxon二进制文件,这些文件中的一个运行中的XQuery,它需要完成评估时间约为2分钟,但是从我的C#应用​​程序在做评估时所经过的时间增加至10分钟左右,而我的天堂还没有能够确定我做错了什么。如何提高C#中撒克逊评估的速度?

这是当我通过命令行运行使用Saxon二进制文件 XQuery的我在做什么:

Query.exe -config:config.xml -q:XQueryTest.txt 

这些都是​​3210的内容:

<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()方法的所有不同重载,并且它们都需要花费很多时间来完成,比从命令行执行时执行所花费的时间多2分钟。

关于使用Saxon的流媒体容量按部分读取文件,由于我们生成的Xqueries,这不是一个选项,因为Xquery可以在XML的任何部分组合信息。

+0

http://stackoverflow.com/questions/2415434/the-limitation-on-the-size-of-net-array显示.NET中任何分配对象的最大大小为2GB。也许撒克逊正在遇到一个.NET内存问题,不得不采取额外的步骤,二进制可能不必采取?也许看看使用的资源会显示二进制文件能够使用额外的内存?对不起,我没有别的东西或撒克逊的特殊经历。干杯! – chryosolo

回答

1

我们已经看到了Java平台和萨克森在某些情况下,在.NET平台上撒克逊之间类似的5:1的比例,我们没有给它为什么会发生,尽管广泛的调查底部。部分原因是它似乎不一致。当我们首次使用IKVMC交叉编译器在.NET上发布Saxon时,这个比例要好得多,.NET上的开销只有25%左右,但从那以后似乎出现了许多技术变化:Java VM拥有得到更快的速度,IKVMC已经从使用GNU Classpath库转向OpenJDK,而.NET本身并没有停滞不前。

这是新的我,虽然,同样的代码应该从.NET命令行运行得更快比它从.NET API运行。

这里最大的区别在于,当您从命令行运行时,Saxon使用Apache Xerces解析器(使用IKVMC转换为.NET代码)构建文档,而在以所示方式使用DocumentBuilder.build()时,你正在使用微软的XmlReader。

我希望,当您提供的(文件系统)的文件建设速度最快的运行URI,但我已经测得它,我不能说。这可能是值得做一些实验(也许用较小的文件)并向我们展示结果。或者,您是否尝试过使用应用程序中的doc()方法,而不是先构建文档?

+0

我们也认为使用URI会给我们带来更好的结果,但事实并非如此,它仍然非常缓慢。我们尝试使用您的最终建议(为什么我们没有想到这一点?),而且速度实际上大大提高了。它仍然有点慢(有点超过3分钟),但在前10分钟附近,这太棒了!我认为我们从来没有想过这种方法,因为我们认为正确的实现应该首先加载XML,然后运行通用的Xquery,而不是在Xquery中对XML路径进行硬编码。 谢谢! – Ricardo

+0

感谢您的信息。这里有一些奇怪的效果,我不明白:我们必须看看我们是否可以重现这一点。 –

+0

在此处记录撒克逊问题:https://saxonica.plan.io/issues/2729 –

0

性能下降是由于使用.NET XmlReader进行解析造成的。使用.NET XML解析器和Saxon接收器的Push/Pull SAX事件处理比使用Saxon中提供的JAXP xerces解析器要慢得多。

要强制JAXP解析器,你可以做以下应该工作:

evaluator.ContextItem = documentBuilder.Build(新的URI(“文件:/// C:\用户\管理员\桌面\ 2GB.xml“));