Azure平台上使用C#脚本的XSLT编译转换速度较慢

Azure平台上使用C#脚本的XSLT编译转换速度较慢,c#,azure,xslt,web-applications,scripting,C#,Azure,Xslt,Web Applications,Scripting,我有一些代码需要运行亚秒,将一个系统的XML输出转换成不同的XML。翻译文件可以随时更改,因此每次执行转换时,我都会加载一个已编译的XSLT转换 我在XSLT中做了一些格式化工作,但决定将来可能要扩展脚本来做其他事情,所以我在XSLT转换中添加了一个使用C#的脚本标记 在我的机器上的开发环境中,我测试了速度,它在大约200毫秒内编译了转换。这段代码最终将在Azure中运行,但有时比我的机器稍微慢一点 完成所有测试后,我将发布到Azure并进行测试。令我恐惧的是,Azure以10000毫秒的速度进

我有一些代码需要运行亚秒,将一个系统的XML输出转换成不同的XML。翻译文件可以随时更改,因此每次执行转换时,我都会加载一个已编译的XSLT转换

我在XSLT中做了一些格式化工作,但决定将来可能要扩展脚本来做其他事情,所以我在XSLT转换中添加了一个使用C#的脚本标记

在我的机器上的开发环境中,我测试了速度,它在大约200毫秒内编译了转换。这段代码最终将在Azure中运行,但有时比我的机器稍微慢一点

完成所有测试后,我将发布到Azure并进行测试。令我恐惧的是,Azure以10000毫秒的速度进行编译。我可以只使用XSLT函数重新编写当前代码,但我想知道社区是否可以帮助我理解Azure为何如此缓慢

我确实理解XSLT转换必须使用CodeDomProvider.CreateProvider启动CodeDomProvider,但即使在Azure中,我认为这也不会花费10秒钟

我的Azure实例使用的是S3服务计划(总共400个ACU,7GB内存),我的利用率从未超过15%

我从XSLT设置中删除了“EnableDocumentFunction”,这似乎一开始就解决了它。事实证明,XsltCompiledTransform可能会被缓存,因为在调用之间等待大约30秒,运行编译仍然需要大约10秒。启用“EnableDocumentFunction”后,我不必在调用之间等待

如果我从XSLT代码(和XSLT设置)中删除脚本,转换将在Azure中快速编译

以下是我使用的代码:

// 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转换

<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>


我希望Azure的工作方式与我的开发机器类似。我意识到由于AppDomain中的安全性,创建CodeDomainProvider可能需要更长的时间,但是10秒似乎很可笑。

你需要将C代码嵌入XSLT代码中,还是不能将其设置在自己的C类中,作为扩展对象使用,方法是将它与
XsltArgumentList
AddExtensionObject
传递到
Transform
方法中?将C代码放入XSLT的想法是我们可以在必要时动态更改转换。我们正在从SQL加载转换字符串,我们可以在生产中更新该字符串,而不需要推送新版本的Web应用程序来更改转换。我认为嵌入一门外语来封装随时间变化的更改不是一个好主意。最好只是更改样式表。此外,您应该使用XSLT已经提供的扩展机制来扩展语言能力。这样,所有外部代码(XSLT调用、扩展实现)都将在同一时间段编译/链接。最后,扩展应该增加容量,而不是数据流。这样一来,变化最大的部分更接近于数据(您的样式表),变化较小的部分更接近于代码(您的扩展)。我不想将任何函数放在Web应用程序的编译版本中,因为这样我必须重新发布应用程序以进行更改,从而导致任务关键型应用程序的停机。我专门为我们内部制定的目的设计了代码,真正的问题是为什么Azure不能以合理的速度运行它。“但是XSLT并没有做到C#所能做到的一切”。很好,它可以格式化一个数字,这与嵌入脚本所做的一样。在许多Microsoft框架中,嵌入脚本的速度比XSLT扩展机制慢。