We have just begun looking at moving an existing ASP.Net application from v1.1 to v2.0. In early tests we appear to be loosing performance when using the XslCompiledTransform object as opposed to the XslTransform object. Our tests have been run with very simple stylesheets as well as the somewhat heavier ones that we currently use in the application. Everything I have read states that the new object is considerably more performant than the old object, yet I am so far unable to proove that this is the case. I am wondering if anyone has experienced anything similar, and also if anyone knows of circumstances that could cause the new object to perform less well than the old one.
Thanks in advance for any help.

XslCompiledTransform
calloatti
CurtTampa
Hi MarkInNB, Mohit6032 et-al
I do not know anything about your specific performance issue, but I am very interested in .NET XML/XSL issues like this.
The beta of our product 'Persistore' includes a class called 'SharedStream' and allows you to drag one or more files (any files, including .xml etc) into a shared memory repository (there is a powerful explorer like tool included in the beta).
Once you have done this, your code be it ASP.NET or any .NET code, is able to disregard disk files and disk file IO and access the SharedStream objects. Because these are designed to be persistent and memory resident they can be read very quickly.
No we haven’t done a great deal of testing in this area, but we can do if you are interested. In essence you can create XslCompiledTransform object and then call the Load and Transform methods using XmlTextReader objects that were created from SharedStream ojects:
SharedStream xsl_strm = some_repository.CreateSharedStream(name, etc....); // open it
XmlTextReader xsl_rdr = new XmlTextReader (xsl_strm);
you can do a similar thing for the XML file.
Basically a SharedStream is a class derived from UnmanagedMemoryStream that contains a pointer to the data in shared memory. By design this data is persistent and always 'there' when your app loads the repository file, to all intents and purpose a SharedStream is a persistent, memory resident file, accessible very rapidly with out any need for ReadFile etc that can burden a file based approach.
Why not get the free beta: http://www.morantex.com/Evaluations.aspx install it, read some of the documentation and let us know how this goes
If you feel the product is helping in any way or can be improved to address any of your problems, then please get in touch we want to make the next beta as useful as we possibly can to real-world developers and designers, we are keen to address any issues or bugs you find and also keen to help you if we can.
Hugh
TimMulholland
I just did a (very) quick test to make sure that the overall idea can run and it seems fine.
I am not in a position to comment on performance, comparative or otherwise at this time however, you will need to run tests yourself and many factors can influence overall performance as you know.
There are bugs of course in the current beta, and one is minor but annoying, it is that you must pass the size of a stream to the CreateSharedStream even if the stream exists; this is logged and will be addressed in the next beta. So having said this, here is my simple test app that demonstrates how SharedStream may be used:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
using Morantex.Storage.Persistore;
namespace XslTester
{
public partial class Form1 : Form
{
Repository db = new Repository();
Dir xsl;
Dir xml;
public Form1()
{
InitializeComponent();
if (db.Load(AllocationMode.Standard, AccessMode.Unprotected, BackingMode.Persistent, Platform.StorageFolder + @"\xlsdata", 4096, false) == false)
if (db.Load(AllocationMode.Standard, AccessMode.Unprotected, BackingMode.Persistent, Platform.StorageFolder + @"\xlsdata", 4096, true))
{
db.CreateDir("", "Xsl", "Xsl source files");
db.CreateDir("", "Xml", "Xml Data Files");
}
else
Application.Exit();
xsl = db.GetDir("Xsl");
xml = db.GetDir("Xml");
}
private void button1_Click(object sender, EventArgs e)
{
/* Open a shared stream containing the XSL */
SharedStream xsl_str = xsl.CreateSharedStream("test_one.xsl", 437, false, FileAccess.ReadWrite);
/* Create new xml text reader using this stream */
XmlTextReader xsl_rdr = new XmlTextReader(xsl_str);
/* Open a shared stream containing the XML */
SharedStream xml_str = xml.CreateSharedStream("test_one.xml", 555, false, FileAccess.ReadWrite);
/* Create a new xml text reader using this stream */
XmlTextReader xml_rdr = new XmlTextReader(xml_str);
XslCompiledTransform tf = new XslCompiledTransform();
XmlTextWriter xml_wrt = new XmlTextWriter("testop", Encoding.ASCII);
tf.Load(xsl_rdr); // Compile
tf.Transform(xml_rdr, xml_wrt);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
Two files an xsl and a suitable xml file, were dragged into the xsl and xml folders of the repository after it was created. It is best to run the app and then terminate it WITHOUT clicking the button, this pre-creates the folders for you.
Then start the analyzer tool and drag an xml and an xsl file into the respective folders, right click each of these to see their sizes and then insert these size into the CreateSharedStream call as the size and rebuild.
When you run the code you can insert breakpoints if you wish in the click handler if you want but if the handler runs you will see the generated output in the file named "testop"
This is a crude demo, and there is a (slightly kludgy) workaround for the size bug that I can post that will remove the need for this hard-coding of size. Also one can eliminate the output file that I coded and send the output to a memory stream or a pre-created SharedStream, but this is not done in this crude demo.
The key thing being shown here is that SharedStream works as described and is processed just like any stream, however the stream is clearly in shared persistent memory and involves NO file IO once the data has been dragged in from the files.
Regards
Hugh
Igor Siticov
Flores
XslCompiledTransform is damn fast, but the speed in question is transformation speed. The price for fast transformation is slow compilation - XslCompiledTransform compiles XSLT into MSIL and this involves multipass optimizing compilation and dynamic code generation.
That is, XslCompiledTransform meant to be precompiled and cached, then you get the best perf.
neilchan
I haven't seen scenarios where XslCompiledTransform.Transform() is slower than XslTransform.Transform().
If you have one please send us XML/XSL files and may be simple code how you call them, because performance may depend on type of cache you use and other external factors.
Address is here: this address.
See also: http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=398461&SiteID=1
Kingsonal
To do this we need your stylesheet and sample xml files.
Please, note that XslTransform is still in .Net v.2 and you can safely move to v2 without migrating to XslCompiledTransform.
msheridan
OK here is a tweaked version that gets around the annoying size bug, it also gens the output as an HTML file, this output file is located in the projects bin/Debug folder incidentally.
Replace the handler shown above, with this one and the size issue is elminated:
private void button1_Click(object sender, EventArgs e)
{
SharedArea xsl_sa = xsl.CreateSharedArea("test_one.xsl", 0);
SharedStream xsl_str = xsl.CreateSharedStream(xsl_sa.Name,xsl_sa.Size ,false, FileAccess.ReadWrite);
XmlTextReader xsl_rdr = new XmlTextReader(xsl_str);
SharedArea xml_sa = xml.CreateSharedArea("test_one.xml", 0);
SharedStream xml_str = xml.CreateSharedStream(xml_sa.Name,xml_sa.Size, false, FileAccess.ReadWrite);
XmlTextReader xml_rdr = new XmlTextReader(xml_str);
XslCompiledTransform tf = new XslCompiledTransform();
XmlTextWriter xml_wrt = new XmlTextWriter("testop.html", Encoding.ASCII);
tf.Load(xsl_rdr);
tf.Transform(xml_rdr, xml_wrt);
}
This is just scratching the surface so far as the product is concerned, you can easily enumerate all shared entities if you wanted to there are plenty of options for experiemnting and load testing and dont forget this supports 32-bit and 64-bit Windows, on the latter you can have some might big repositories!
Rgds
Hugh