I have some code that needs to run sub-second that translates the output of XML from one system into different XML. The translation file can change at any time, so I am loading a compiled XSLT transform for each time that I do the transformation.
I was doing some formatting in XSLT, but decided that in the future I might want to expand the scripting to do other things, so I added a script tag using C# into the XSLT transform.
In my development environment on my machine, I tested the speed and it compiled the transform in around 200ms. This code will ultimately run in Azure, but sometimes that is slightly slower than my machine.
Once all my testing was done, I published to Azure and tested. To my horror, Azure does the compilation in 10000ms instead. I am able to re-write my current code using only XSLT functions, but was wondering if the community might help me understand why Azure was SOOOOO slow.
I do understand that the XSLT transform has to spin up a CodeDomProvider using CodeDomProvider.CreateProvider, but even in Azure that should not take 10 seconds I would think.
My Azure instance is using an S3 service plan (400 total ACU, 7GB memory), and I never go over 15% utilization.
I removed "EnableDocumentFunction" from the XsltSettings and that seemed to fix it at first. It turns out that the XsltCompiledTransform might be cached, because it I wait about 30 seconds between calls, it still takes around 10 seconds to run the compilation. With the "EnableDocumentFunction" turned on, I didn't have to wait between calls.
If I remove the script from the XSLT code (and the XsltSettings), the transform compiles very quickly in Azure.
Here is the code I was using:
// C# code
string Xslt = ...; // Shown below
using (StringReader srt = new StringReader(Xslt))
{
using (XmlReader xrt = XmlReader.Create(srt))
{
XslCompiledTransform xslt = new XslCompiledTransform();
XsltSettings xsltSettings = new XsltSettings() { EnableScript = true };
xslt.Load(xrt, xsltSettings, null); // This takes 10 seconds on Azure, 200ms in dev
}
}
XSLT transform
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:user="urn:my-scripts">
<xsl:output method="xml" indent="yes" />
<msxsl:script language="C#" implements-prefix="user">
<!--<msxsl:assembly name="System.Web" />
<msxsl:using namespace="System.Web" />-->
<![CDATA[
public string FormatCurrency(decimal Currency)
{
return Currency.ToString("###0.00###");
}
public string Upper(string Text) { return Text.ToUpper(); }
]]>
</msxsl:script>
<xsl:template match="ROOT">
<!-- … (Short XSLT script) -->
</xsl:template>
</xsl:stylesheet>
I expect Azure to work similarly to my development machine. I realize that creating a CodeDomProvider might take longer because of security in the AppDomain, but 10 seconds seems ridiculous.