2016-07-08 87 views
2

由於XPath 2.0/XSLT 2.0,我想將我的XslCompiledTransform遷移到Saxon 9.7.0.6 HE,但它比.NET慢。C#Parallel.ForEach XslCompiledTransform與Saxon 9.7.0.6 HE

我測試的每個版本與一個默認的拷貝的ident XSLT和15.000 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 

所以主減速是調試器本身,但僅限於撒克遜人。 現在它只需要.NET版本的兩倍,它不是超級棒,但我認爲我可以做到這一點。

我能做些什麼來讓撒克遜人變得更快?也許玩代碼或使用EE而不是HE?

這裏是一些詳細的基準測試信息,主要的性能問題是DocumentBuilder.Build方法。但是,即使是變換本身是兩倍以上.NET版本慢:

撒克遜:

Saxon

.NET:

.NET

+0

你試過沒有運行並行測試?如果時差顯着變化,那麼它可能會提示原因。 –

+0

您正在使用哪個版本的Saxon,只是爲了讓我們瞭解您的比較是基於什麼。 –

+0

我更新了我的問題,並添加了正常的foreach和撒克遜版本的時間。 – Tony

回答

0

我對Saxon的DocumentBuilder.Build(XmlReader)做了測試並執行了兩個測試。

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); 
} 

Console.WriteLine("XslCompiledTransform:"); 
for (int i = 0; i < 3; i++) 
{ 
    sw.Reset(); 
    sw.Start(); 
    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); 
    }); 
    sw.Stop(); 
    Console.WriteLine("Duration: " + sw.Elapsed); 
    RemoveFiles(output); 
} 

的結果是:

Saxon: 210.679ms 
XslCompiledTransform: 179.129ms 

我覺得這是一個偉大的結果,薩克森版本只需要更多的17,61%的時間比XslCompiledTransform版本。我可以使用XPath 2.0和Xslt 2.0,並且只有不到20%的性能損失。

撒克遜:

Saxon

XslCompiledTransform:

enter image description here

+0

文本中的計時結果(「Saxon:179.129ms」,「XslCompiledTransform:210.679ms」)無意中交換了嗎? –

+0

是的你說得對,謝謝。 – Tony

1

具有性能,魔鬼總是在細節中。這聽起來像是一個值得做詳細研究的場景,所以如果您可以向我們(Saxonica)提供我們需要運行的所有內容,我們很樂意看一看。

從數字中可以看出,第一件事情是,MS處理器比Saxon的並行化要快得多。這可能是由於NamePool爭用:我們已經做了很多工作來減少NamePool對最近版本的爭用,但這是針對「典型工作負載」的,我們需要檢查,例如,您的文檔是否全部使用相同的詞彙表名。

我想要確定的第一件事是成本的多少是文件的建立和轉化的程度。根據答案,後續調查將採用完全不同的課程。 (結果樹的序列化成本也可能是一個因素,但那是不尋常的。)

Saxon的.NET版本已知比Java版本慢得多。多年前曾經有過約30%的開銷,但似乎有所增加,所以現在慢了3-5倍,儘管付出了相當大的努力,但我們還沒有設法解決原因。我們非常依賴IKVMC交叉編譯器技術和OpenJDK庫。

+1

令人遺憾的是,MSFT並沒有從xsl-1.0上移開,但在他們的防守中,他們已經生產出了一款速度非常快的處理器,至今仍爲其他競爭對手設定了高標準的處理器。我有很長一段時間想在我的.net應用程序中使用xsl-2(現在是xsl-3),但每次我檢查我的選項時,我已經總結了成本(不僅是產品的成本)好處並不值得。我發現我可以通過使用xml.net的c#擴展來達到理想的平衡/妥協。也就是說,我保持警惕,並希望看到OP進一步測試的結果。 –

+0

我很慚愧地承認我用Visual Studio Debugger進行了測試。所以主要的性能問題就解決了。你能否證實對於Saxon的.NET實現,速度慢2倍是「沒問題」? – Tony

+0

我同意@PhilBlackburn很難與MS產品在性能上展開競爭。對於大多數人來說,即使機器性能出現成本,開發人員的生產效率提高一倍也是值得的 - 機器價格便宜,開發人員昂貴;毫無疑問,XSLT 2.0爲您提供了巨大的生產力提升;它還爲您提供了諸如分組和正則表達式等功能,可以提高性能。我們在幾年前做了一些測量(在XML倫敦報告),並且根據確切的工作量,比較是高度可變的。 –