Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Parallel.ForEach XslCompiledTransform vs.Saxon 9.7.0.6 HE_C#_Xslt_Saxon_Parallel.foreach_Xslcompiledtransform - Fatal编程技术网

C#Parallel.ForEach XslCompiledTransform vs.Saxon 9.7.0.6 HE

C#Parallel.ForEach XslCompiledTransform vs.Saxon 9.7.0.6 HE,c#,xslt,saxon,parallel.foreach,xslcompiledtransform,C#,Xslt,Saxon,Parallel.foreach,Xslcompiledtransform,由于XPath 2.0/XSLT2.0,我想将XslCompiledTransform迁移到Saxon 9.7.0.6 HE,但它比.NET慢得多 我使用默认的副本标识XSLT和15000个xml文件测试了每个版本: Saxon with Parallel.ForEach: 00:05:02.9013605 XslCompiledTransform with Parallel.ForEach: 00:00:15.6724146 Saxon with foreach: 00:10:09.7763

由于XPath 2.0/XSLT2.0,我想将XslCompiledTransform迁移到Saxon 9.7.0.6 HE,但它比.NET慢得多

我使用默认的副本标识XSLT和15000个xml文件测试了每个版本:

Saxon with Parallel.ForEach: 00:05:02.9013605
XslCompiledTransform with Parallel.ForEach: 00:00:15.6724146

Saxon with foreach: 00:10:09.7763861
XslCompiledTransform with foreach: 00:03:00.3483324
我希望我做错了什么,XslCompiledTransform:

XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl);

XmlWriterSettings writerSettings = xslt.OutputSettings.Clone();
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Ignore;
readerSettings.XmlResolver = null;

Parallel.ForEach(files, file =>
{
    string target = Path.Combine(output, Path.GetFileName(file));
    using (XmlReader xr = XmlReader.Create(file, readerSettings))
    using (XmlWriter xw = XmlWriter.Create(target, writerSettings))
        xslt.Transform(xr, xw);
});
撒克逊版本:

Processor processor = new Processor();
DocumentBuilder docBuilder = processor.NewDocumentBuilder();
docBuilder.DtdValidation = false;
docBuilder.SchemaValidationMode = SchemaValidationMode.None;
docBuilder.WhitespacePolicy = WhitespacePolicy.PreserveAll;
XsltCompiler compiler = processor.NewXsltCompiler();
XsltExecutable executable = compiler.Compile(new Uri(xsl));

Parallel.ForEach(files, file =>
{
    string target = Path.Combine(output, Path.GetFileName(file));
    XsltTransformer transformer = executable.Load();
    XdmNode input = docBuilder.Build(new Uri(file));
    transformer.InitialContextNode = input;
    Serializer serializer = new Serializer();
    serializer.SetOutputFile(target);
    transformer.Run(serializer);
});
更新

我在没有进行Visual Studio调试的情况下进行了另一个测试,结果好多了:

Saxon: 00:00:41.5990128
XslCompiledTransform: 00:00:19.0441044
因此,主要的减速是调试器本身,但仅限于Saxon。 现在它只需要两倍于.NET版本的时间,它不是超级棒,但我想我可以接受

我能做些什么让萨克森更快吗?也许玩代码或者用EE代替HE

下面是一些详细的基准测试信息,主要的性能问题是DocumentBuilder.Build方法。但即使是转换本身也比.NET版本慢两倍多:

撒克逊人:

.NET:


就性能而言,魔鬼总是在细节中。这听起来像是一个值得做一些详细研究的场景,因此,如果您能为我们(Saxonica)提供运行它所需的一切,我们将很乐意看一看

从您的数据中可以注意到的第一件事是,MS处理器从并行化中获得的速度比Saxon要快得多。这可能是因为名称池争用:在最近的版本中,我们已经做了很多工作来减少名称池争用,但这是针对“典型工作负载”,例如,我们需要检查您的文档是否都使用相同的名称词汇表

我想确定的第一件事是文档构建的成本和转换的成本。根据答案,后续调查将采取完全不同的过程。(结果树的序列化成本也可能是一个因素,但这并不常见。)


众所周知,Saxon的.NET版本要比Java版本慢得多。几年前,经常性开支约为30%,但这似乎有所增加,所以现在慢了3-5倍,尽管付出了相当大的努力,我们还没有找到原因。我们在这里非常依赖IKVMC交叉编译器技术和OpenJDK库。

我使用DocumentBuilder.Build(XmlReader)for Saxon进行了测试,并执行了这两个测试

Console.WriteLine("Saxon:");
for (int i = 0; i < 3; i++)
{
    sw.Reset();
    sw.Start();
    Parallel.ForEach(files, file =>
    {
        string target = Path.Combine(output, Path.GetFileName(file));
        XsltTransformer transformer = executable.Load();
        XdmNode input = null;
        using (XmlReader xr = XmlReader.Create(file, readerSettings))
            input = docBuilder.Build(xr);
        transformer.InitialContextNode = input;
        Serializer serializer = new Serializer();
        serializer.SetOutputFile(target);
        transformer.Run(serializer);
    });
    sw.Stop();
    Console.WriteLine("Duration: " + sw.Elapsed);
    RemoveFiles(output);
}
我认为这是一个很好的结果,Saxon版本只需要比XslCompiledTransform版本多17,61%的时间。我可以使用XPath2.0和XSLT2.0,但性能损失不到20%

撒克逊人:

XslCompiledTransform:

XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xsl);

XmlWriterSettings writerSettings = xslt.OutputSettings.Clone();
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Ignore;
readerSettings.XmlResolver = null;

Parallel.ForEach(files, file =>
{
    string target = Path.Combine(output, Path.GetFileName(file));
    using (XmlReader xr = XmlReader.Create(file, readerSettings))
    using (XmlWriter xw = XmlWriter.Create(target, writerSettings))
        xslt.Transform(xr, xw);
});

您是否尝试过在没有并行测试的情况下运行测试?如果时差发生显著变化,则可能会提示原因。您使用的是哪一版本的Saxon,只是为了让我们了解您的比较依据。我更新了我的问题,并添加了普通foreach和Saxon版本的时间。嗯,对于性能问题,我们还需要知道您是否使用HE或PE或EE版本,因为商业版本的性能肯定比开源HE更好。我确实使用HE版本。也许有人可以用PE版本来测试它,我不知道可能会有显著的性能差异。不幸的是,MSFT没有从xsl-1.0开始,但为他们辩护,他们生产了一种非常快的处理器,至今仍为其他人的竞争设置了高标准。我一直希望在我的.net应用程序中使用xsl-2(现在是xsl-3),但每次我回顾我的选择时,我都会得出结论:改变的成本(不仅仅是产品成本)和好处是不值得的。我发现,使用xml.net的c#扩展可以实现理想的平衡/折衷。尽管如此,我仍然保持警惕,并渴望看到OP进一步测试的结果。我很惭愧地承认我使用Visual Studio调试器进行了测试。从而解决了主要的性能问题。你能确认2倍的速度对于Saxon的.NET实现来说是“可以的”吗?我同意@PhilBlackburn的观点,即在性能上很难与MS产品竞争。对大多数人来说,即使在机器性能上存在成本,将开发人员的生产力翻一番也是值得的——机器便宜,开发人员昂贵;毫无疑问,XSLT2.0大大提高了生产率;此外,它还提供了分组和正则表达式等有助于提高性能的功能。我们在几年前做了一些测量(在XML London上报道),根据具体的工作负载,比较是高度可变的。文本(“Saxon:179.129ms”,“XslCompiledTransform:210.679ms”)中的计时结果是否被无意地交换了?
Saxon: 210.679ms
XslCompiledTransform: 179.129ms