Skip to content

Instantly share code, notes, and snippets.

@m0sa
Created September 24, 2015 14:02
Show Gist options
  • Save m0sa/33506d5610f0a152bc4d to your computer and use it in GitHub Desktop.
Save m0sa/33506d5610f0a152bc4d to your computer and use it in GitHub Desktop.
<Query Kind="Program">
<NuGetReference>Microsoft.AspNet.Mvc</NuGetReference>
<NuGetReference>Microsoft.CodeAnalysis.CSharp</NuGetReference>
<Namespace>System.CodeDom.Compiler</Namespace>
<Namespace>System.Web.Razor</Namespace>
<Namespace>System.Web.WebPages.Razor</Namespace>
<Namespace>Microsoft.CodeAnalysis</Namespace>
<Namespace>Microsoft.CodeAnalysis.CSharp</Namespace>
<Namespace>Microsoft.CodeAnalysis.Emit</Namespace>
<Namespace>Microsoft.CodeAnalysis.Text</Namespace>
</Query>
void Main()
{
var counts = new int[] { 5, 1000, 10000, 25000, 50000 };
var host = WebRazorHostFactory.CreateDefaultHost("test.chstml", "test.cshtml");
var references = AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.IsDynamic && !string.IsNullOrWhiteSpace(a.Location))
.Select(x => (MetadataReference)MetadataReference.CreateFromFile(x.Location, MetadataReferenceProperties.Assembly))
.ToArray();
foreach (var count in counts)
{
var source = string.Join(Environment.NewLine, Enumerable.Repeat("<p>@DateTime.Now</p>", count));
using (var rdr = new StringReader(source))
using (var provider = CodeDomProvider.CreateProvider("csharp"))
using (var generatedString = new StringWriter())
using (var generatedStream = new MemoryStream())
using (var generatedWriter = new StreamWriter(generatedStream))
{
var engine = new RazorTemplateEngine(host);
var razorOut = engine.GenerateCode(rdr, null, null, "test.cshtml");
var codeGenOptions = new CodeGeneratorOptions { VerbatimOrder = true, ElseOnClosing = false, BlankLinesBetweenMembers = false };
provider.GenerateCodeFromCompileUnit(razorOut.GeneratedCode, generatedWriter, codeGenOptions);
provider.GenerateCodeFromCompileUnit(razorOut.GeneratedCode, generatedString, codeGenOptions);
// rewind
generatedWriter.Flush();
generatedStream.Position = 0;
generatedString.Flush();
var cases = new Dictionary<string, SourceText>
{
{ "stream", SourceText.From(generatedStream, Encoding.UTF8) },
{ "string", SourceText.From(generatedString.GetStringBuilder().ToString(), Encoding.UTF8) },
};
// if (count == 5) Console.WriteLine(cases["string"].ToString());
foreach (var c in cases)
{
var name = $"test.{c.Key}.{count}.dll";
var args = CSharpCommandLineParser.Default.Parse(
$"/subsystemversion:6.00 /target:library /utf8output /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu /errorreport:prompt /warn:4 /define:DEBUG;TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /out:{name}"
.Split(' '), ".", null);
var sw = Stopwatch.StartNew();
var compilation = CSharpCompilation.Create(
options: args.CompilationOptions.WithAssemblyIdentityComparer(DesktopAssemblyIdentityComparer.Default),
references: references,
syntaxTrees: new[] {
SyntaxFactory.ParseSyntaxTree(c.Value, path: $"test.{c.Key}.{count}.cshtml"),
},
assemblyName: name);
var t1 = sw.ElapsedMilliseconds;
sw.Restart();
using (var peStream = new MemoryStream(10000000))
using (var pdbStream = new MemoryStream(10000000))
using (var win32Resources = compilation.CreateDefaultWin32Resources(
versionResource: true,
noManifest: true,
manifestContents: null,
iconInIcoFormat: null))
{
var emitResult = compilation.Emit(
peStream: peStream,
pdbStream: pdbStream,
options: args.EmitOptions,
xmlDocumentationStream: null,
win32Resources: win32Resources);
if (!emitResult.Success)
foreach (var d in emitResult.Diagnostics)
Console.WriteLine(d);
}
sw.Stop();
Console.WriteLine($"{count,10} {c.Key,10} {t1,7}ms {sw.ElapsedMilliseconds,7}ms");
}
}
}
}
@m0sa
Copy link
Author

m0sa commented Sep 24, 2015

Output

         5     stream       0ms      21ms
         5     string       0ms       8ms
      1000     stream      15ms     115ms
      1000     string      15ms      88ms
     10000     stream     165ms     789ms
     10000     string     171ms     773ms
     25000     stream     424ms    2149ms
     25000     string     604ms    2137ms
     50000     stream     834ms    4321ms
     50000     string    1057ms    4242ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment