2016-07-08 4 views
2

Я хотел перенести свой XslCompiledTransform в Saxon 9.7.0.6 HE из-за XPath 2.0/XSLT 2.0, но это медленнее, чем .NET.C# Parallel.ForEach XslCompiledTransform vs. Saxon 9.7.0.6 HE

Я проверил каждую версию с копией по умолчанию идента 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 

Так что главный замедляются был сам отладчик, но только для Saxon. Теперь это занимает всего лишь два раза времени версии .NET, но это не очень здорово, но я думаю, что смогу с этим справиться.

Есть ли что-нибудь, что я могу сделать, чтобы сделать Саксон быстрее? Может быть, играть с кодом или использовать EE вместо HE?

Вот некоторые подробные контрольные данные, основная проблема с производительностью - это метод DocumentBuilder.Build. Но даже преобразование сама по себе более чем в два раза медленнее версии .NET:

Saxon:

Saxon

.NET:

.NET

+0

Вы пробовали запустить тест без параллели? Если разница во времени значительно меняется, это может дать нам подсказку. –

+0

Какая версия Saxon вы используете, просто чтобы мы могли понять, на чем базируется ваше сравнение. –

+0

Я обновил свой вопрос и добавил время для обычного foreach и Saxon Version. – Tony

ответ

0

Я проверил с DocumentBuilder.Build (XmlReader) для 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); 
} 

и

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 

Я думаю, что это отличный результат, версия Saxon нужно только 17,61% больше времени, чем версия XslCompiledTransform. Я могу использовать XPath 2.0 и Xslt 2.0 и иметь потерю производительности менее 20%.

Saxon:

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, но в своей защите они выпустили очень быстрый процессор, который до сих пор устанавливает высокий бар для других, чтобы конкурировать. У меня было долгое время использовать xsl-2 (и теперь xsl-3) в моих .net-приложениях, но каждый раз, когда я просматриваю свои варианты, я заключил стоимость изменения (а не только стоимость продукта) против пособие не имеет смысла.Я обнаружил, что могу достичь идеального баланса/компромисса, используя расширения C# с xml.net. Тем не менее, я остаюсь настороженным и заинтересованным видеть результаты любых дальнейших испытаний OP. –

+0

Мне стыдно признаться, что я протестировал с помощью Visual Studio Debugger. Таким образом, основная проблема производительности решена. Можете ли вы подтвердить, что в 2 раза медленнее «хорошо» для реализации Saxon .NET? – Tony

+0

Я согласен с @PhilBlackburn, что очень сложно конкурировать с продуктом MS от производительности. Для большинства людей удвоение производительности разработчиков стоит делать, даже если есть затраты на производительность машины - машины дешевы, разработчики стоят дорого; и нет никаких сомнений в том, что XSLT 2.0 дает вам большой прирост производительности; также он дает вам функции, такие как группировка и регулярные выражения, которые помогают производительности. Мы провели несколько измерений пару лет назад (сообщается в XML London), и сравнения сильно варьируются в зависимости от точной рабочей нагрузки. –