GrabDuck

Using Precompiled XSLT in .NET

:

Using XSLT in .NET

If you specify a file using

XSLCompiledTranform.Load(string filename)

the first thing XSLCompiledTranform is going to do is to emit/compile a set of unloadable DynamicMethods.

Although this is going really fast this overhead costs around 50 - 200ms. So if total time for your conversion is around that time, using precompiled XSLT's can really improve things quite a bit. We use this scenario to do high performance yet standard translations in WCF-Services.

To precompile your XSLT's you have 2 options:

The XSLTCompiler XSLTC.exe

First option is shipped with .NET 3.5 there and is a tool called XSLTC.exe which is basically a wrapper around the static XSLCompiledTransform.CompileToType() function. There is an excellent article by Anton Lapounov . It even gives you some tips to speed things further up using ngen.

I previously stated that XSLTC.exe can only compile one XSLT per assembly, but Andrew proved me wrong.
I tried:

XSLTC.exe *.xslt

which won't work but if you take a closer look at the options

xsltc [options] [/class: ] [[/class: ] ...]


XSLTC.exe /out:MyXSLT.dll a.xslt b.xslt c.xslt

should compile the XSLT's into a single assembly.

IronXSLT

Second option for this job is called IronXSLT. It is a Visual Studio plug in, that allows you to create a XSLT Library Project. You simply add your XSLT's to the project and after you build the solution they will be compiled into one DLL assembly. I installed it and it works fine with Visual Studio 2008 SP1. After you installed it you have a new project type called XSLT - XSLT Library. To configure it right click it in the solution explorer and select "Properties".

The problem. Unfortunately it seems that its creator Oleg Tkachenko has abandoned his project and no download is working anymore on the projects website.

I found one of the last working IronXSLT downloads here . I will try to contact Oleg in order to get the source published somewhere.

Performance Comparison

Attached to the already above mentioned article of Anton Lapounov there is some test code attached.

I ran a couple of test and got the following results:

using XSLTranform class

XSLTranform
.Load(string filename)

Load time: 35,86 ms
Load time: 1,533 ms
Load time: 1,450 ms
Load time: 1,441 ms
Load time: 1,504 ms
------------------------
Transform time: 51,94 ms
Transform time: 51,29 ms
Transform time: 49,46 ms
Transform time: 51,10 ms
Transform time: 48,77 ms

using XSLCompiledTranform loading tranformation from file

XSLCompiledTranform
.Load(string filename)


Load time: 51,86 ms

Load time: 2,640 ms
Load time: 2,556 ms
Load time: 2,704 ms
Load time: 2,644 ms
------------------------
Transform time: 56,89 ms
Transform time: 1,909 ms
Transform time: 1,680 ms
Transform time: 4,948 ms
Transform time: 1,427 ms

using XSLCompiledTranform loading XSLTC precompiled Transformation

XSLCompiledTranform.Load(type T)

Load time: 5,252 ms
Load time: 0,057 ms
Load time: 0,034 ms
Load time: 0,061 ms
Load time: 0,031 ms
------------------------
Transform time: 8,936 ms
Transform time: 2,302 ms
Transform time: 1,545 ms
Transform time: 1,457 ms
Transform time: 1,505 ms

using XSLCompiledTranform loading XSLTC precompiled and ngen'd Transformation

XSLCompiledTranform
.Load(type T)

Load time: 4,596 ms
Load time: 0,052 ms
Load time: 0,035 ms
Load time: 0,032 ms
Load time: 0,031 ms
------------------------
Transform time: 2,917 ms
Transform time: 2,446 ms
Transform time: 1,584 ms
Transform time: 1,457 ms
Transform time: 1,472 ms