CompilerParameters.GenerateInMemory =错误的性能问题

我正在使用RazorEngine来解析应用程序中的html模板,并且正在编写一些NUnit测试来描述性能区域并调查潜在的问题。 看起来,当指定GenerateInMemory = false ,我的代码受到巨大的性能影响。

在NUnit中运行每个测试时,在CompileAssemblyFromDom()方法中花费的总滴答如下所示:

GenerateInMemory = false:      354,493,052 ticks
GenerateInMemory = true:     6,669,711,153 ticks

这比我预计的某些磁盘IO的额外成本更具有极端的影响。 此外,看起来这次与测试的大小不成线性关系。 例如,当我运行200次迭代测试而不是1000次(内存= false)时,结果为118M滴答,这1000次测试迭代的归一化为591M滴答。 这比相应的测试载入内存稍大一些,但是当全尺寸测试终于完成时(我认为它是悬挂的,但是在写这个问题时完成了),它的实际性能仍然要低一个数量级。

保存大量动态程序集时,是否有任何理由对性能产生巨大影响?

测试代码:

        for (int i = 0; i < 1000; i++)
        {
            string s = "<div>" + i + " some random text blah blah... no code specified</div>";
            parser.GetHtmlFromTemplate(s, i.ToString());

        }

        /*
         * Result:
         *     _codeDomProvider.CompileAssemblyFromDom:       354493052 ticks
         */
        /* ... collect timing stats */

和GetHtmlFromTemplate()代码:

    public string GetHtmlFromTemplate(string template, string templateCacheName)
    {
        if (template == string.Empty) return string.Empty;

        ITemplate templateInstance = templateService.GetTemplate(template, null, templateCacheName);
        return templateInstance.Run(new ExecuteContext());
    }

一堆不相关的代码发生在这里,最终我们到达问题区域,这是CodeDomProvider用于编译代码的地方:

            var compileTimer = new Stopwatch();
            compileTimer.Start();
            var compileUnit = GetCodeCompileUnit(context.ClassName, context.TemplateContent, context.Namespaces,
                                                 context.TemplateType, context.ModelType);
            compileTimer.Stop();



            var @params = new CompilerParameters
            {
                GenerateInMemory = InMemory, //in memory is a property of this object, and is set accordingly for each test
                GenerateExecutable = false,
                IncludeDebugInformation = false,
                CompilerOptions = "/target:library /optimize"
            };

            //{...} do some reflection to get the referenced assemblies


            var compileFromDomTimer = new Stopwatch();
            compileFromDomTimer.Start();

            var tuple = Tuple.Create(_codeDomProvider.CompileAssemblyFromDom(@params, compileUnit), someString);
            compileFromDomTimer.Stop();

TLDR:在将少量程序集(<200)保存到磁盘时, CompileAssemblyFromDom()方法的性能比加载到内存更差,但是当数量增加(〜500-1000)时,性能会降低几个数量级? 什么导致这种奇怪的行为?


我已经找到了这个链接,作者Rick Strahl说CodeDomProvider编译器在应用程序域中加载了已编译的程序集:

应用程序域加载程序集,但它们无法卸载它们!

这也是MSDN所说的:看到这个。

所以问题在于程序集都驻留在内存中,从而减慢了系统的速度。

链接地址: http://www.djcxy.com/p/65097.html

上一篇: CompilerParameters.GenerateInMemory = false performance issue

下一篇: Use RazorEngine IsolatedTemplateService with resolver?